
#include "bzRuby.h"

#include <iostream>


#define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)

// ruby modules declarations
static VALUE bzflag_module;

// ruby class declarations
static VALUE plugin;

static VALUE c_event_data;
static VALUE c_ctf_capture_event_data;
static VALUE c_player_die_event_data;
static VALUE c_player_spawn_event_data;
static VALUE c_chat_event_data;
static VALUE c_player_join_part_event_data;
static VALUE c_unknown_slash_command_event_data;
static VALUE c_get_player_spawn_pos_event_data;
static VALUE c_allow_player_event_data;
static VALUE c_tick_event_data;
static VALUE c_generate_world_event_data;
static VALUE c_get_player_info_event_data;
static VALUE c_get_auto_team_event_data;
static VALUE c_allow_spawn_data;
static VALUE c_list_server_update_event;
static VALUE c_ban_event_data;
static VALUE c_host_ban_event_data;
static VALUE c_kick_event_data;
static VALUE c_kill_event_data;
static VALUE c_player_paused_event_data;
static VALUE c_message_filtered_event_data;
static VALUE c_game_start_end_event_data;
static VALUE c_slash_command_event_data;
static VALUE c_player_auth_event_data;
static VALUE c_server_msg_event_data;
static VALUE c_shot_fired_event_data;
static VALUE c_player_update_event_data;
static VALUE c_net_transfer_event_data;
static VALUE c_loging_event_data;
static VALUE c_shot_ended_event_data;
static VALUE c_flag_transferred_event_data;
static VALUE c_flag_grabbed_event_data;
static VALUE c_flag_dropped_event_data;

static VALUE c_player_record;

// ruby id declarations
static int id_show;
static int id_objid;


extern VALUE plugin_list;

/* call-seq:
 *	plugin.register
 *
 *	This method will register the ruby plugin so it will respond
 *	to the gameserver events.
 */

static VALUE
plugin_register(VALUE self)
{
	rb_ary_push(plugin_list, self);
	return Qnil;
}


bool load_ruby_plugin(const char * plugin, const char * param) 
{
	int error = 0;

	rb_protect(wrap_rb_require, reinterpret_cast<VALUE>(plugin), &error);

	if (error)
		return false;

	bz_debugMessagef(2,"Ruby Plugin: %s loaded",plugin);


	return true;

}


VALUE 
wrap_rb_require(VALUE arg) 
{
	const char *plugin = reinterpret_cast<const char*>(arg);
	rb_require(plugin);
	return Qnil;
}


void emit_ruby_event(char * eMsg, VALUE data)
{

	int id_meth	= rb_intern(eMsg);
	
	for (int i = 0; i < RARRAY(plugin_list)->len; i++) 
	{
		if (rb_respond_to(rb_ary_entry(plugin_list,i), id_meth) != 0 )
			VALUE result = protected_ruby_event(rb_ary_entry(plugin_list,i), id_meth, data);
	}
}

void emit_ruby_event(char * eMsg)
{
	int id_meth	= rb_intern(eMsg);
	
	for (int i = 0; i < RARRAY(plugin_list)->len; i++) 
	{
		if (rb_respond_to(rb_ary_entry(plugin_list,i), id_meth) != 0 )
			VALUE result = rb_funcall(rb_ary_entry(plugin_list,i), id_meth, 0);
	}

}


VALUE
protected_ruby_event(VALUE event, VALUE method, VALUE data)
{
	int error=0;
	VALUE args[3];
	VALUE result;

	args[0] = event;
	args[1] = method;
	args[2] = data;

	result = rb_protect(wrap_ruby_event, reinterpret_cast<VALUE>(args), &error);

	return error ? Qnil : result;
}


VALUE
wrap_ruby_event(VALUE args)
{
	VALUE *values = (VALUE*) args;
	VALUE event = values[0];
	VALUE method = values[1];
	VALUE data = values[2];

	return rb_funcall(event, method, 1, data);
}

//
// Module Bzflag methods (not really OO style ... something to fix later)
//

/* call-seq:
 * 	bz_send_text_message(from, to, message)
 *
 *	Sends a text message to the specified user. BZ_SERVER should be
 *	used for messages from the server. If the message is sent to
 *	BZ_ALL_USERS  it will send the message to all connected users.
 *	Likewise if it is set to BZ_ADMIN_CHANNEL  it will be sent to all
 *	users with the ADMINMESSAGERECEIVE permission.
 */

static VALUE
bzflag_bz_sendTextMessage(VALUE self, VALUE from, VALUE to, VALUE message)
{
	bz_sendTextMessage (NUM2INT(from), NUM2INT(to), RSTRING(StringValue(message))->ptr);

	return Qnil;
}

/* call-seq:
 *	bz_get_player_index_list -> array
 *
 *	Returns an array which contains all the player ids that are
 *	known to the server.
 */

static VALUE
bzflag_bz_getPlayerIndexList(VALUE self)
{

	bzAPIIntList *playerIndexes = bz_newIntList();
	bz_getPlayerIndexList(playerIndexes);

	VALUE player_indexes = rb_ary_new();

	for (unsigned int i = 0; i < playerIndexes->size(); i++)
		rb_ary_push(player_indexes, INT2FIX(playerIndexes->get(i)));	


	return player_indexes;
}

/* call-seq:
 *	bz_has_perm?(player_id, permission) -> true or false
 *
 * 	 Returns true if the player has the permission, if not 
 * 	 it returns false.
 */

static VALUE
bzflag_bz_hasPerm(VALUE self, VALUE playerID , VALUE perm)
{

	if (bz_hasPerm(FIX2INT(playerID), RSTRING(StringValue(perm))->ptr))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_grant_perm(player_id, permission) -> true or false
 *
 * 	This method grants the player the given permission and
 * 	returns true on success, false on failure.
 */

static VALUE
bzflag_bz_grantPerm(VALUE self, VALUE playerID , VALUE perm)
{

	if (bz_grantPerm(FIX2INT(playerID), RSTRING(StringValue(perm))->ptr))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_revoke(player_id, permission) -> true or false
 *
 * 	This method revokes the given permission from the player
 * 	and returns true on success, false on failure.
 */

static VALUE
bzflag_bz_revokePerm(VALUE self, VALUE playerID , VALUE perm)
{

	if (bz_revokePerm(FIX2INT(playerID), RSTRING(StringValue(perm))->ptr))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_get_player_flag(player_id) -> string or nil
 *
 * 	This method returns the flagtype the given player is 
 * 	holding.
 */

static VALUE
bzflag_bz_getPlayerFlag(VALUE self, VALUE playerID)
{
	if (!bz_getPlayerFlag(FIX2INT(playerID)))
		return Qnil;

	return rb_str_new2(bz_getPlayerFlag(FIX2INT(playerID)));
}

/* call-seq:
 *	bz_is_player_paused(player_id) -> true or false
 *
 * 	This method returns true if a player is paused , false
 * 	when not paused.
 */

static VALUE
bzflag_bz_isPlayerPaused(VALUE self, VALUE playerID)
{

	if (bz_isPlayerPaused(FIX2INT(playerID)))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_get_player_lag(player_id) -> Fixnum
 *
 * 	This method returns the amount of lag a given player has.
 */

static VALUE
bzflag_bz_getPlayerLag(VALUE self, VALUE playerID)
{
	return INT2FIX(bz_getPlayerLag(FIX2INT(playerID)));
}

/* call-seq:
 *	bz_get_player_jitter(player_id) -> Fixnum
 *
 * 	This method returns the amount of jitter a given player has.
 */

static VALUE
bzflag_bz_getPlayerJitter(VALUE self, VALUE playerID)
{
	return INT2FIX(bz_getPlayerJitter(FIX2INT(playerID)));
}

/* call-seq:
 *	bz_get_player_packetloss(player_id) -> Float
 *
 * 	This method returns the amount of packetloss a given player has.
 */

static VALUE
bzflag_bz_getPlayerPacketloss(VALUE self, VALUE playerID)
{
	return rb_float_new(bz_getPlayerLag(FIX2INT(playerID)));
}



/* call-seq:
 *	bz_set_player_operator(player_id) -> true or false
 *
 * 	This method gives the given player id operator status.
 * 	On success it returns true on failure it returns false.
 */ 

static VALUE
bzflag_bz_resetPlayerScore(VALUE self, VALUE playerID)
{
  bool killed = bz_killPlayer(FIX2INT(playerID), true);
  bool reseted = bz_resetPlayerScore(FIX2INT(playerID));

 if ( killed && reseted ) 
	return Qtrue;
 
  return Qfalse;
}




/* call-seq:
 *	bz_set_player_operator(player_id) -> true or false
 *
 * 	This method gives the given player id operator status.
 * 	On success it returns true on failure it returns false.
 */ 

static VALUE
bzflag_bz_setPlayerOperator(VALUE self, VALUE playerID)
{

	if (bz_setPlayerOperator(FIX2INT(playerID)))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_get_team_player_limit(team) -> Fixnum
 *
 * 	This method returns the player limit of the given team.
 */ 

static VALUE
bzflag_bz_getTeamPlayerLimit(VALUE self, VALUE team)
{
	return INT2NUM(bz_getTeamPlayerLimit((bz_eTeamType) FIX2INT(team)));
}


/* call-seq:
 *	bz_get_group_list -> array
 *
 * 	This method returns an array which contains all groups.
 */ 

static VALUE
bzflag_bz_getGroupList(VALUE self)
{
	int i;
	VALUE groups = rb_ary_new();

	for (i = 0; i < (bz_getGroupList())->size(); i++)
		rb_ary_push(groups, rb_str_new2((bz_getGroupList())->get(i).c_str()));

	return groups;
}

/* call-seq:
 *	bz_get_group_perms(group) -> array
 *
 * 	This method returns an array which contains all perms of a  
 * 	given group.
 */ 

static VALUE
bzflag_bz_getGroupPerms(VALUE self, VALUE group)
{
	int i;
	VALUE perms = rb_ary_new();

	for (i = 0; i < (bz_getGroupPerms(RSTRING(StringValue(group))->ptr))->size(); i++)
		rb_ary_push(perms, rb_str_new2((bz_getGroupPerms(RSTRING(StringValue(group))->ptr))->get(i).c_str()));

	return perms;
}

/* call-seq:
 *	bz_group_allow_perms(group,perm) -> true or false
 *
 * 	This method adds the specified permission to the specified group.
 * 	On success it return true, on failure it returns false.
 */ 

static VALUE
bzflag_bz_groupAllowPerm(VALUE self, VALUE group, VALUE perm)
{

	if (bz_groupAllowPerm(RSTRING(StringValue(group))->ptr, RSTRING(StringValue(perm))->ptr))	
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	bz_sent_fetch_res_message(player_id,url) -> true or false
 *
 * 	This method ... fix me ...
 */ 

static VALUE
bzflag_bz_sentFetchResMessage(VALUE self, VALUE playerID, VALUE URL)
{

	if (bz_sentFetchResMessage(FIX2INT(playerID), RSTRING(StringValue(URL))->ptr))	
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	bz_debug_message(debug_level, message) 
 *
 * 	This method prints a message at the given debug level.
 */ 

static VALUE
bzflag_bz_debugMessage(VALUE self, VALUE debugLevel, VALUE message)
{

	bz_debugMessage(FIX2INT(debugLevel),RSTRING(StringValue(message))->ptr);

	return Qnil;
}

/* call-seq:
 *	bz_getDebugLevel -> Fixnum	
 *
 * 	This method returns the currently set debug level value.
 */ 

static VALUE
bzflag_bz_getDebugLevel(VALUE self)
{
	return INT2FIX(bz_getDebugLevel());
}

/* call-seq:
 *	bz_kick_user(player_id,reason,notify) -> true or false	
 *
 * 	This method kicks the user with the give player id.
 * 	On success it returns true , on failure it returns false.
 */ 

static VALUE
bzflag_bz_kickUser(VALUE self, VALUE playerID, VALUE reason, VALUE notify)
{
	bool bnotify;

	if ( TYPE(notify) == T_TRUE)	
		bnotify = true;

	if ( TYPE(notify) == T_FALSE)	
		bnotify = false;

	if ( bz_kickUser(FIX2INT(playerID), RSTRING(StringValue(reason))->ptr, bnotify))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_ip_ban_user(player_id,ip,time,reason) -> true or false	
 *
 * 	This method bans the user with the give player id on ip basis.
 * 	The ban duration time and reason can be specified.
 * 	On success it returns true , on failure it returns false.
 */ 

static VALUE
bzflag_bz_IPBanUser(VALUE self, VALUE playerID, VALUE ip, VALUE time, VALUE reason)
{

	if ( bz_IPBanUser(FIX2INT(playerID), RSTRING(StringValue(ip))->ptr, FIX2INT(time), RSTRING(StringValue(reason))->ptr))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_ip_unban_user(ip) -> true or false	
 *
 * 	This method unbans the specified ipaddress.
 * 	On success it returns true , on failure it returns false.
 */ 

static VALUE
bzflag_bz_IPUnbanUser(VALUE self, VALUE ip)
{

	if ( bz_IPUnbanUser(RSTRING(StringValue(ip))->ptr))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_get_reports -> array
 *
 * 	This method returns an array of strings who contain the 
 * 	reports submitted by players.
 */ 

static VALUE
bzflag_bz_getReports(VALUE self)
{

	int i;
	VALUE reports = rb_ary_new();

	for (i = 0; i < bz_getReports()->size(); i++)
		rb_ary_push(reports, rb_str_new2(bz_getReports()->get(i).c_str()));

	return reports;

}

/* call-seq:
 *	bz_set_time_limit(timelimit) -> true or false
 *
 * 	This method sets the given timelimit.
 * 	On success it returns true on failure it returns false.
 */ 

static VALUE
bzflag_bz_setTimeLimit(VALUE self, VALUE timeLimit)
{

	if (bz_setTimeLimit((float) NUM2DBL(timeLimit)))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_get_time_limit -> float
 *
 * 	This method returns the currently set timelimit.
 */ 

static VALUE
bzflag_bz_getTimeLimit(VALUE self)
{

	return rb_float_new(bz_getTimeLimit());

}

/* call-seq:
 *	bz_is_time_manual_start? -> true or false
 *
 * 	This method returns true when -timemanual is set,
 * 	false when not set.
 */ 

static VALUE
bzflag_bz_isTimeManualStart(VALUE self)
{

	if (bz_isTimeManualStart())
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_is_count_down_active? -> true or false
 *
 * 	This method returns true when there is a countdown active,
 * 	false when not active.
 */ 

static VALUE
bzflag_bz_isCountDownActive(VALUE self)
{

	if (bz_isCountDownActive())
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	bz_is_count_down_in_progress? -> true or false
 *
 * 	This method returns true when there is a countdown in progress,
 * 	false when not progress.
 */ 

static VALUE
bzflag_bz_isCountDownInProgress(VALUE self)
{
	if (bz_isCountDownInProgress())
		return Qtrue;

	return Qfalse;

}

//
// bz_EventData
//

VALUE c_event_data_class(void)
{
	return c_event_data;
}

/* call-seq:
 *	event_data.event_type -> Fixnum
 *
 * 	This method returns the eventtype value.
 */ 

static VALUE
eventData_eventType(VALUE self)
{
	bz_EventData *eventData;

	Data_Get_Struct(self, bz_EventData, eventData);

	return INT2FIX(eventData->eventType);
}


//
// bz_CTFCaptureEventData
//

VALUE c_ctf_capture_event_data_class(void)
{
	return c_ctf_capture_event_data;
}

/* call-seq:
 *	event_data.team_capped -> Fixnum
 *
 * 	This method returns the team that got captured.
 */ 

static VALUE
cTFCaptureEventData_getTeamCapped(VALUE self)
{
	bz_CTFCaptureEventData *eventData;

	Data_Get_Struct(self, bz_CTFCaptureEventData, eventData);

	return INT2FIX(eventData->teamCapped);
}

/* call-seq:
 *	event_data.team_capping -> Fixnum
 *
 * 	This method returns the team that made the capture.
 */ 

static VALUE
cTFCaptureEventData_getTeamCapping(VALUE self)
{
	bz_CTFCaptureEventData *eventData;

	Data_Get_Struct(self, bz_CTFCaptureEventData, eventData);

	return INT2FIX(eventData->teamCapping);
}

/* call-seq:
 *	event_data.player_capping -> Fixnum
 *
 * 	This method returns the id of the player that made the 
 * 	capture.
 */ 


static VALUE
cTFCaptureEventData_getPlayerCapping(VALUE self)
{

	bz_CTFCaptureEventData *eventData;

	Data_Get_Struct(self, bz_CTFCaptureEventData, eventData);

	return INT2FIX(eventData->playerCapping);

}


/* call-seq:
 *	event_data.pos -> Array
 *
 * 	This method returns the position of the player who made 
 * 	the capture.
 */ 


static VALUE
cTFCaptureEventData_getPos(VALUE self)
{

	bz_CTFCaptureEventData *eventData;

	Data_Get_Struct(self, bz_CTFCaptureEventData, eventData);

	VALUE pos = rb_ary_new();

	rb_ary_push(pos, rb_float_new(eventData->pos[0]));
	rb_ary_push(pos, rb_float_new(eventData->pos[1]));
	rb_ary_push(pos, rb_float_new(eventData->pos[2]));

	return pos;

}

/* call-seq:
 *	event_data.rot -> Float
 *
 * 	This method returns the rotation angle of the player who made 
 * 	the capture.
 */ 

static VALUE
cTFCaptureEventData_getRot(VALUE self)
{
	bz_CTFCaptureEventData *eventData;

	Data_Get_Struct(self, bz_CTFCaptureEventData, eventData);

	return rb_float_new(eventData->rot);
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the capture occured.
 */ 

static VALUE
cTFCaptureEventData_getTime(VALUE self)
{
	bz_CTFCaptureEventData *eventData;

	Data_Get_Struct(self, bz_CTFCaptureEventData, eventData);

	return rb_float_new(eventData->time);
}

//
// bz_PlayerDieEventData
//

VALUE c_player_die_event_data_class(void)
{
	return c_player_die_event_data;
}


/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE
playerDieEventData_getPlayerID(VALUE self)
{

	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	return INT2FIX(eventData->playerID);

}


/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of the player who invoked the event.
 */

static VALUE
playerDieEventData_getTeam(VALUE self)
{
	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 * 	event_data.killer_id -> Fixnum
 *
 * Returns the playerid of the player who made the kill.
 */


static VALUE
playerDieEventData_getKillerID(VALUE self)
{
	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	return INT2FIX(eventData->killerID);

}

/* call-seq:
 * 	event_data.killer_team -> Fixnum
 *
 * Returns the team of the player who made the kill.
 */

static VALUE
playerDieEventData_getKillerTeam(VALUE self)
{

	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	return INT2FIX(eventData->killerTeam);

}

/* call-seq:
 * 	event_data.flag_killed_with -> String
 *
 * Returns the flagtype the player got killed with.
 */

static VALUE
playerDieEventData_getFlagKilledWith(VALUE self)
{

	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	return rb_str_new2(eventData->flagKilledWith.c_str());

}

/* call-seq:
 * 	event_data.shot_id -> Fixnum
 *
 * Returns the shotid of the shot that made the kill. 
 */

static VALUE
playerDieEventData_getShotID(VALUE self)
{

	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	return INT2FIX(eventData->shotID);

}

/* call-seq:
 *	event_data.pos -> Array
 *
 * 	This method returns the position where the player died.
 */ 

static VALUE
playerDieEventData_getPos(VALUE self)
{

	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	VALUE pos = rb_ary_new();

	rb_ary_push(pos, rb_float_new(eventData->pos[0]));
	rb_ary_push(pos, rb_float_new(eventData->pos[1]));
	rb_ary_push(pos, rb_float_new(eventData->pos[2]));

	return pos;

}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the player died.
 */ 

static VALUE
playerDieEventData_getTime(VALUE self)
{
	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	return rb_float_new(eventData->time);
}

/* call-seq:
 *	event_data.rot -> Float
 *
 * 	This method returns the last known rotation angle of the player who
 * 	died.
 */ 

static VALUE
playerDieEventData_getRot(VALUE self)
{
	bz_PlayerDieEventData *eventData;

	Data_Get_Struct(self, bz_PlayerDieEventData, eventData);

	return rb_float_new(eventData->rot);
}

//
// bz_PlayerSpawnEventData
//

VALUE c_player_spawn_event_data_class(void)
{
	return c_player_spawn_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE
playerSpawnEventData_getPlayerID(VALUE self)
{

	bz_PlayerSpawnEventData *eventData;

	Data_Get_Struct(self, bz_PlayerSpawnEventData, eventData);

	return INT2FIX(eventData->playerID);

}

/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of the player who invoked the event.
 */

static VALUE 
playerSpawnEventData_getTeam(VALUE self)
{
	bz_PlayerSpawnEventData *eventData;

	Data_Get_Struct(self, bz_PlayerSpawnEventData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 *	event_data.pos -> Array
 *
 * 	This method returns the position where the player spawned.
 */ 

static VALUE
playerSpawnEventData_getPos(VALUE self)
{

	bz_PlayerSpawnEventData *eventData;

	Data_Get_Struct(self, bz_PlayerSpawnEventData, eventData);

	VALUE pos = rb_ary_new();

	rb_ary_push(pos, rb_float_new(eventData->pos[0]));
	rb_ary_push(pos, rb_float_new(eventData->pos[1]));
	rb_ary_push(pos, rb_float_new(eventData->pos[2]));

	return pos;

}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the player spawned.
 */ 

static VALUE 
playerSpawnEventData_getTime(VALUE self)
{
	bz_PlayerSpawnEventData *eventData;

	Data_Get_Struct(self, bz_PlayerSpawnEventData, eventData);

	return rb_float_new(eventData->time);
}

/* call-seq:
 *	event_data.rot -> Float
 *
 * 	This method returns the rotation angle of the player who
 * 	spawned.
 */ 

static VALUE 
playerSpawnEventData_getRot(VALUE self)
{
	bz_PlayerSpawnEventData *eventData;

	Data_Get_Struct(self, bz_PlayerSpawnEventData, eventData);
	
	return rb_float_new(eventData->rot);
}

//
// bz_ChatEventData
// 


VALUE c_chat_event_data_class(void)
{
	return c_chat_event_data;
}

/* call-seq:
 *	event_data.from -> Fixnum
 *
 * 	This method returns the player id of the player who send the
 * 	message.
 */ 

static VALUE 
chatEventData_getFrom(VALUE self)
{
	bz_ChatEventData *eventData;

	Data_Get_Struct(self, bz_ChatEventData, eventData);

	return INT2FIX(eventData->from);
}

/* call-seq:
 *	event_data.to -> Fixnum
 *
 * 	This method returns the player id of the player for who the message
 * 	is intented.
 */ 

static VALUE 
chatEventData_getTo(VALUE self)
{
	bz_ChatEventData *eventData;

	Data_Get_Struct(self, bz_ChatEventData, eventData);

	return INT2FIX(eventData->to);
}

/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of to who the message was send.
 */

static VALUE 
chatEventData_getTeam(VALUE self)
{
	bz_ChatEventData *eventData;

	Data_Get_Struct(self, bz_ChatEventData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 * 	event_data.message -> String
 *
 * Returns the chat message.
 */

static VALUE
chatEventData_getMessage(VALUE self)
{
	bz_ChatEventData *eventData;

	Data_Get_Struct(self, bz_ChatEventData, eventData);

	return rb_str_new2(eventData->message.c_str());
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the chat event occured.
 */ 

static VALUE 
chatEventData_getTime(VALUE self)
{
	bz_ChatEventData *eventData;

	Data_Get_Struct(self, bz_ChatEventData, eventData);
	
	return rb_float_new(eventData->time);
}


// bz_PlayerJoinPartEventData

VALUE c_player_join_part_event_data_class(void)
{
	return c_player_join_part_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE 
playerJoinPartEventData_getPlayerID(VALUE self)
{
	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of the player who invoked the event.
 */

static VALUE 
playerJoinPartEventData_getTeam(VALUE self)
{
	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 * 	event_data.callsign -> String
 *
 * Returns the callsign of the player who joined or parted.
 */

static VALUE
playerJoinPartEventData_getCallsign(VALUE self)
{

	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);

	return rb_str_new2(eventData->callsign.c_str());

}

/* call-seq:
 * 	event_data.email -> String
 *
 * Returns the email of the player who joined or parted.
 */

static VALUE
playerJoinPartEventData_getEmail(VALUE self)
{

	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);

	return rb_str_new2(eventData->email.c_str());

}

/* call-seq:
 * 	event_data.verified? -> true or false
 *
 * Returns true if the player is verified , false if not.
 */

static VALUE 
playerJoinPartEventData_isVerified(VALUE self)
{
	
	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);
	
	if (eventData->verified)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 * 	event_data.global_user -> String
 *
 * Returns the global user.
 */

static VALUE
playerJoinPartEventData_getGlobalUser(VALUE self)
{

	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);

	return rb_str_new2(eventData->globalUser.c_str());

}

/* call-seq:
 * 	event_data.ip_address -> String
 *
 * Returns the ip adddress of the player who joined or parted.
 */

static VALUE
playerJoinPartEventData_getIpAddress(VALUE self)
{

	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);

	return rb_str_new2(eventData->ipAddress.c_str());

}

/* call-seq:
 * 	event_data.reason -> String
 *
 * Returns the reason why the player parted the game.
 */

static VALUE
playerJoinPartEventData_getReason(VALUE self)
{

	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);

	return rb_str_new2(eventData->reason.c_str());

}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the player joined or parted 
 * 	the game.
 */ 

static VALUE 
playerJoinPartEventData_getTime(VALUE self)
{
	bz_PlayerJoinPartEventData *eventData;

	Data_Get_Struct(self, bz_PlayerJoinPartEventData, eventData);
	
	return rb_float_new(eventData->time);
}


//
// bz_UnknownSlashCommandEventData
// 

VALUE c_unknown_slash_command_event_data_class(void)
{
	return c_unknown_slash_command_event_data;
}

/* call-seq:
 * 	event_data.from -> Fixnum
 *
 * Returns the player id from the player that issued the slash command.
 */

static VALUE 
unknownSlashCommandEventData_getFrom(VALUE self)
{
	bz_UnknownSlashCommandEventData *eventData;

	Data_Get_Struct(self, bz_UnknownSlashCommandEventData, eventData);

	return INT2FIX(eventData->from);
}

/* call-seq:
 * 	event_data.message -> String
 *
 * Returns the slash message the player issued.
 */

static VALUE
unknownSlashCommandEventData_getMessage(VALUE self)
{

	bz_UnknownSlashCommandEventData *eventData;

	Data_Get_Struct(self, bz_UnknownSlashCommandEventData, eventData);

	return rb_str_new2(eventData->message.c_str());

}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the player typed in the command.
 */ 

static VALUE 
unknownSlashCommandEventData_getTime(VALUE self)
{
	bz_UnknownSlashCommandEventData *eventData;

	Data_Get_Struct(self, bz_UnknownSlashCommandEventData, eventData);
	
	return rb_float_new(eventData->time);
}

/* call-seq:
 *	event_data.handled? -> true or false
 *
 * 	This method returns true when the event is already handled, false if
 * 	not.
 */ 

static VALUE 
unknownSlashCommandEventData_isHandled(VALUE self)
{
	bz_UnknownSlashCommandEventData *eventData;

	Data_Get_Struct(self, bz_UnknownSlashCommandEventData, eventData);
	
	if (eventData->handled)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	event_data.handled=(true or false) -> self
 *
 * 	This method allows to set the event as handled or not.
 */ 

static VALUE 
unknownSlashCommandEventData_setHandled(VALUE self, VALUE new_handled)
{
	bz_UnknownSlashCommandEventData *eventData;

	Data_Get_Struct(self, bz_UnknownSlashCommandEventData, eventData);

	switch (TYPE(new_handled)) 
	{
     case T_TRUE:
		eventData->handled=true;
		break;
	case T_FALSE:
		eventData->handled=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}

//
// bz_AllowPlayerEventData
//

VALUE c_allow_player_event_data_class(void)
{
	return c_allow_player_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE 
allowPlayerEventData_getPlayerID(VALUE self)
{
	bz_AllowPlayerEventData *eventData;

	Data_Get_Struct(self, bz_AllowPlayerEventData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 * 	player.callsign -> String
 *
 * This method returns the callsign of the player.
 */


static VALUE
allowPlayerEventData_getCallsign(VALUE self)
{
	bz_AllowPlayerEventData *eventData;

	Data_Get_Struct(self, bz_AllowPlayerEventData, eventData);

	return rb_str_new2(eventData->callsign.c_str());
}

/* call-seq:
 * 	event_data.ip_address -> String
 *
 * Returns the ip address which got banned.
 */

static VALUE
allowPlayerEventData_getIpAddress(VALUE self)
{
	bz_AllowPlayerEventData *eventData;

	Data_Get_Struct(self, bz_AllowPlayerEventData, eventData);

	return rb_str_new2(eventData->ipAddress.c_str());
}

/* call-seq:
 * 	event_data.reason -> String
 *
 * Returns the reason why the player is not allowed.
 */

static VALUE
allowPlayerEventData_getReason(VALUE self)
{
	bz_AllowPlayerEventData *eventData;

	Data_Get_Struct(self, bz_AllowPlayerEventData, eventData);

	return rb_str_new2(eventData->reason.c_str());
}

/* call-seq:
 * 	event_data.allow? -> true or false
 *
 * Returns true if the player is allowed to join , false if not.
 */

static VALUE 
allowPlayerEventData_isAllow(VALUE self)
{
	bz_AllowPlayerEventData *eventData;

	Data_Get_Struct(self, bz_AllowPlayerEventData, eventData);
	
	if (eventData->allow)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 * 	event_data.allow=(true or false) -> self
 *
 * This method makes it possible to modify the allow variable.
 */

static VALUE 
allowPlayerEventData_setAllow(VALUE self, VALUE allow)
{
	bz_AllowPlayerEventData *eventData;

	Data_Get_Struct(self, bz_AllowPlayerEventData, eventData);

	switch (TYPE(allow)) 
	{
     case T_TRUE:
		eventData->allow=true;
		break;
	case T_FALSE:
		eventData->allow=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the invent was invoked.
 */ 

static VALUE 
allowPlayerEventData_getTime(VALUE self)
{
	bz_AllowPlayerEventData *eventData;

	Data_Get_Struct(self, bz_AllowPlayerEventData, eventData);
	
	return rb_float_new(eventData->time);
}


//
// bz_TickEventData
//


VALUE c_tick_event_data_class(void)
{
	return c_tick_event_data;
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the invent was invoked.
 */ 

static VALUE 
tickEventData_getTime(VALUE self)
{
	bz_TickEventData *eventData;

	Data_Get_Struct(self, bz_TickEventData, eventData);
	
	return rb_float_new(eventData->time);
}


//
// bz_GenerateWorldEventData
//

VALUE c_generate_world_event_data_class(void)
{
	return c_generate_world_event_data;
}

/* call-seq:
 * 	event_data.generated? -> true or false
 *
 * This method returns true if the world is generated, false if not.
 */

static VALUE 
generateWorldEventData_isGenerated(VALUE self)
{
	bz_GenerateWorldEventData *eventData;

	Data_Get_Struct(self, bz_GenerateWorldEventData, eventData);
	
	if (eventData->generated)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 * 	event_data.generated=(true or false) -> self
 *
 * This method makes it possible to flag a world as generated or not.
 */

static VALUE 
generateWorldEventData_setGenerated(VALUE self, VALUE generated)
{
	bz_GenerateWorldEventData *eventData;

	Data_Get_Struct(self, bz_GenerateWorldEventData, eventData);

	switch (TYPE(generated)) 
	{
     case T_TRUE:
		eventData->generated=true;
		break;
	case T_FALSE:
		eventData->generated=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}

/* call-seq:
 * 	event_data.ctf? -> true or false
 *
 * This method returns true if it is a ctf world , false if not.
 */

static VALUE 
generateWorldEventData_isCtf(VALUE self)
{
	bz_GenerateWorldEventData *eventData;

	Data_Get_Struct(self, bz_GenerateWorldEventData, eventData);
	
	if (eventData->ctf)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 * 	event_data.rabbit? -> true or false
 *
 * This method returns true if it is a rabbit world , false if not.
 */

static VALUE 
generateWorldEventData_isRabbit(VALUE self)
{
	bz_GenerateWorldEventData *eventData;

	Data_Get_Struct(self, bz_GenerateWorldEventData, eventData);
	
	if (eventData->rabbit)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 * 	event_data.open_ffa? -> true or false
 *
 * This method returns true if it is a open ffa world , false if not.
 */

static VALUE 
generateWorldEventData_isOpenFFA(VALUE self)
{
	bz_GenerateWorldEventData *eventData;

	Data_Get_Struct(self, bz_GenerateWorldEventData, eventData);
	
	if (eventData->openFFA)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 * 	event_data.world_file -> String
 *
 * This method returns the wordfile of the world.
 */

static VALUE
generateWorldEventData_getWorldFile(VALUE self)
{
	bz_GenerateWorldEventData *eventData;

	Data_Get_Struct(self, bz_GenerateWorldEventData, eventData);

	return rb_str_new2(eventData->worldFile.c_str());
}

/* call-seq:
 * 	event_data.world_file=(String world_file) -> self
 *
 * This method makes it possible to set the worldfile.
 */

static VALUE
generateWorldEventData_setWorldFile(VALUE self, VALUE worldFile)
{
	bz_GenerateWorldEventData *eventData;

	Data_Get_Struct(self, bz_GenerateWorldEventData, eventData);

	eventData->worldFile = RSTRING(StringValue(worldFile))->ptr;

	return self;
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the invent was invoked.
 */ 

static VALUE 
generateWorldEventData_getTime(VALUE self)
{
	bz_GenerateWorldEventData *eventData;

	Data_Get_Struct(self, bz_GenerateWorldEventData, eventData);
	
	return rb_float_new(eventData->eventTime);
}

//
// bz_GetPlayerInfoEventData
//

VALUE c_get_player_info_event_data_class(void)
{
	return c_get_player_info_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE 
getPlayerInfoEventData_getPlayerID(VALUE self)
{
	bz_GetPlayerInfoEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerInfoEventData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 * 	player.callsign -> String
 *
 * This method returns the callsign of the player.
 */

static VALUE
getPlayerInfoEventData_getCallsign(VALUE self)
{
	bz_GetPlayerInfoEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerInfoEventData, eventData);

	return rb_str_new2(eventData->callsign.c_str());

}

/* call-seq:
 * 	event_data.ip_address -> String
 *
 * Returns the ip address which got banned.
 */

static VALUE
getPlayerInfoEventData_getIpAddress(VALUE self)
{
	bz_GetPlayerInfoEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerInfoEventData, eventData);

	return rb_str_new2(eventData->ipAddress.c_str());
}

/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of the player who invoked the event.
 */

static VALUE 
getPlayerInfoEventData_getTeam(VALUE self)
{
	bz_GetPlayerInfoEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerInfoEventData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 *	event_data.admin? -> true or false
 *
 * 	This method returns true if the player is an admin, else it 
 * 	returns	false
 */ 

static VALUE 
getPlayerInfoEventData_isAdmin(VALUE self)
{
	bz_GetPlayerInfoEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerInfoEventData, eventData);
	
	if (eventData->admin)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	event_data.verified? -> true or false
 *
 * 	This method returns true if the player is verified, else it returns
 * 	false
 */ 

static VALUE 
getPlayerInfoEventData_isVerified(VALUE self)
{
	bz_GetPlayerInfoEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerInfoEventData, eventData);
	
	if (eventData->verified)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	event_data.registered? -> true or false
 *
 * 	This method returns true if the player is registered, else it returns
 * 	false
 */ 

static VALUE 
getPlayerInfoEventData_isRegistered(VALUE self)
{
	bz_GetPlayerInfoEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerInfoEventData, eventData);
	
	if (eventData->registered)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the invent was invoked.
 */ 

static VALUE 
getPlayerInfoEventData_getTime(VALUE self)
{
	bz_GetPlayerInfoEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerInfoEventData, eventData);
	
	return rb_float_new(eventData->time);
}


//
// bz_GetAutoTeamEventData
//


VALUE c_get_auto_team_event_data_class(void)
{
	return c_get_auto_team_event_data;
}

// typo in bzfsAPI (playeID)

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE 
getAutoTeamEventData_getPlayerID(VALUE self)
{
	bz_GetAutoTeamEventData *eventData;

	Data_Get_Struct(self, bz_GetAutoTeamEventData, eventData);

	return INT2FIX(eventData->playeID);
}

/* call-seq:
 * 	player.callsign -> String
 *
 * This method returns the callsign of the player.
 */

static VALUE
getAutoTeamEventData_getCallsign(VALUE self)
{
	bz_GetAutoTeamEventData *eventData;

	Data_Get_Struct(self, bz_GetAutoTeamEventData, eventData);

	return rb_str_new2(eventData->callsign.c_str());

}

/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of the player who invoked the event.
 */

static VALUE 
getAutoTeamEventData_getTeam(VALUE self)
{
	bz_GetAutoTeamEventData *eventData;

	Data_Get_Struct(self, bz_GetAutoTeamEventData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 *	event_data.handled? -> true or false
 *
 * 	This method returns true when the event is already handled, false if
 * 	not.
 */ 

static VALUE 
getAutoTeamEventData_isHandled(VALUE self)
{
	bz_GetAutoTeamEventData *eventData;

	Data_Get_Struct(self, bz_GetAutoTeamEventData, eventData);
	
	if (eventData->handled)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	event_data.handled=(true or false) -> self
 *
 * 	This method allows to set the event as handled or not.
 */ 

static VALUE 
getAutoTeamEventData_setHandled(VALUE self, VALUE new_handled)
{
	bz_GetAutoTeamEventData *eventData;

	Data_Get_Struct(self, bz_GetAutoTeamEventData, eventData);

	switch (TYPE(new_handled)) 
	{
     case T_TRUE:
		eventData->handled=true;
		break;
	case T_FALSE:
		eventData->handled=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}

//
// bz_AllowSpawnData
//

VALUE c_allow_spawn_data_class(void)
{
	return c_allow_spawn_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE 
allowSpawnData_getPlayerID(VALUE self)
{
	bz_AllowSpawnData *eventData;

	Data_Get_Struct(self, bz_AllowSpawnData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of the player who invoked the event.
 */

static VALUE 
allowSpawnData_getTeam(VALUE self)
{
	bz_AllowSpawnData *eventData;

	Data_Get_Struct(self, bz_AllowSpawnData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 *	event_data.handled? -> true or false
 *
 * 	This method returns true when the event is already handled, false if
 * 	not.
 */ 

static VALUE 
allowSpawnData_isHandled(VALUE self)
{
	bz_AllowSpawnData *eventData;

	Data_Get_Struct(self, bz_AllowSpawnData, eventData);
	
	if (eventData->handled)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	event_data.handled=(true or false) -> self
 *
 * 	This method allows to set the event as handled or not.
 */ 

static VALUE 
allowSpawnData_setHandled(VALUE self, VALUE new_handled)
{
	bz_AllowSpawnData *eventData;

	Data_Get_Struct(self, bz_AllowSpawnData, eventData);

	switch (TYPE(new_handled)) 
	{
     case T_TRUE:
		eventData->handled=true;
		break;
	case T_FALSE:
		eventData->handled=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}

/* call-seq:
 * 	event_data.allow? -> true or false
 *
 * Returns true if the player is allowed to spawn , false if not.
 */

static VALUE 
allowSpawnData_isAllow(VALUE self)
{
	bz_AllowSpawnData *eventData;

	Data_Get_Struct(self, bz_AllowSpawnData, eventData);
	
	if (eventData->allow)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 * 	event_data.allow=(true or false) -> self
 *
 * This method makes it possible to modify the allow variable.
 */

static VALUE 
allowSpawnData_setAllow(VALUE self, VALUE allow)
{
	bz_AllowSpawnData *eventData;

	Data_Get_Struct(self, bz_AllowSpawnData, eventData);

	switch (TYPE(allow)) 
	{
     case T_TRUE:
		eventData->allow=true;
		break;
	case T_FALSE:
		eventData->allow=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the invent was invoked.
 */ 

static VALUE 
allowSpawnData_getTime(VALUE self)
{
	bz_AllowSpawnData *eventData;

	Data_Get_Struct(self, bz_AllowSpawnData, eventData);
	
	return rb_float_new(eventData->time);
}


//
// bz_GetPlayerSpawnPosEventData
//


VALUE c_get_player_spawn_pos_event_data_class(void)
{
	return c_get_player_spawn_pos_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE 
getPlayerSpawnPosEventData_getPlayerID(VALUE self)
{
	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of the player who invoked the event.
 */

static VALUE 
getPlayerSpawnPosEventData_getTeam(VALUE self)
{
	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 *	event_data.pos -> Array
 *
 * 	This method returns the position where the player was supposed to spawn,
 * 	if not changed.
 */ 

static VALUE 
getPlayerSpawnPosEventData_getPos(VALUE self)
{
	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);

	VALUE pos = rb_ary_new();

	rb_ary_push(pos, rb_float_new(eventData->pos[0]));
	rb_ary_push(pos, rb_float_new(eventData->pos[1]));
	rb_ary_push(pos, rb_float_new(eventData->pos[2]));

	return pos;
}

/* call-seq:
 *	event_data.pos=(Array pos) -> self
 *
 * 	This method makes it possible to change the spawn position of a
 * 	player.
 */ 

static VALUE 
getPlayerSpawnPosEventData_setPos(VALUE self, VALUE new_pos)
{

	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);

	eventData->pos[0] = NUM2DBL(rb_ary_entry(new_pos,0));
	eventData->pos[1] = NUM2DBL(rb_ary_entry(new_pos,1));
	eventData->pos[2] = NUM2DBL(rb_ary_entry(new_pos,2));

	return self;
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the invent was invoked.
 */ 

static VALUE 
getPlayerSpawnPosEventData_getTime(VALUE self)
{
	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);
	
	return rb_float_new(eventData->time);
}

/* call-seq:
 *	event_data.rot -> Float
 *
 * 	This method returns the rotation angle of the player who is 
 * 	going to spawn.
 */ 

static VALUE 
getPlayerSpawnPosEventData_getRot(VALUE self)
{
	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);
	
	return rb_float_new(eventData->rot);
}

/* call-seq:
 *	event_data.rot=(Float rot) -> self
 *
 * 	This method makes it possible to change the rotation of a
 * 	player.
 */ 

static VALUE 
getPlayerSpawnPosEventData_setRot(VALUE self, VALUE new_rot)
{
	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);
	
	eventData->rot = NUM2DBL(new_rot);

	return self;
}

/* call-seq:
 *	event_data.handled? -> true or false
 *
 * 	This method returns true when the event is already handled, false if
 * 	not.
 */ 

static VALUE 
getPlayerSpawnPosEventData_isHandled(VALUE self)
{
	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);
	
	if (eventData->handled)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	event_data.handled=(true or false) -> self
 *
 * 	This method allows to set the event as handled or not.
 */ 

static VALUE 
getPlayerSpawnPosEventData_setHandled(VALUE self, VALUE new_handled)
{
	bz_GetPlayerSpawnPosEventData *eventData;

	Data_Get_Struct(self, bz_GetPlayerSpawnPosEventData, eventData);

	switch (TYPE(new_handled)) 
	{
     case T_TRUE:
		eventData->handled=true;
		break;
	case T_FALSE:
		eventData->handled=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}

//
// bz_ListServerUpdateEvent
//


VALUE c_list_server_update_event_class(void)
{
	return c_list_server_update_event;
}

/* call-seq:
 *	event_data.address -> String
 *
 * 	This method returns the list server address.
 */ 

static VALUE
listServerUpdateEvent_getAddress(VALUE self)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);

	return rb_str_new2(eventData->address.c_str());
}

/* call-seq:
 *	event_data.address=(String address) -> self
 *
 * 	This method makes it possible to change the list server
 * 	address which the server will contact.
 */ 

static VALUE
listServerUpdateEvent_setAddress(VALUE self, VALUE address)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);

	eventData->address = RSTRING(StringValue(address))->ptr;

	return self;
}

/* call-seq:
 *	event_data.description -> String
 *
 * 	This method returns the list server description of the server.
 */ 

static VALUE
listServerUpdateEvent_getDescription(VALUE self)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);

	return rb_str_new2(eventData->description.c_str());
}

/* call-seq:
 *	event_data.description=(String description) -> self
 *
 * 	This method makes it possible to change the description of 
 * 	the server in the server list.
 */ 

static VALUE
listServerUpdateEvent_setDescription(VALUE self, VALUE description)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);

	eventData->description = RSTRING(StringValue(description))->ptr;

	return self;
}

/* call-seq:
 *	event_data.groups -> String
 *
 * 	This method returns the list server groups for the server.
 */ 

static VALUE
listServerUpdateEvent_getGroups(VALUE self)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);

	return rb_str_new2(eventData->groups.c_str());
}

/* call-seq:
 *	event_data.groups=(String groups) -> self
 *
 * 	This method makes it possible to change the groups of
 * 	the server.
 */ 

static VALUE
listServerUpdateEvent_setGroups(VALUE self, VALUE groups)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);

	eventData->groups = RSTRING(StringValue(groups))->ptr;

	return self;
}

/* call-seq:
 *	event_data.handled? -> true or false
 *
 * 	This method returns true when the event is already handled, false if
 * 	not.
 */ 

static VALUE 
listServerUpdateEvent_isHandled(VALUE self)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);
	
	if (eventData->handled)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	event_data.handled=(true or false) -> self
 *
 * 	This method allows to set the event as handled or not.
 */ 

static VALUE 
listServerUpdateEvent_setHandled(VALUE self, VALUE new_handled)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);

	switch (TYPE(new_handled)) 
	{
     case T_TRUE:
		eventData->handled=true;
		break;
	case T_FALSE:
		eventData->handled=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the list server got updated.
 */ 

static VALUE 
listServerUpdateEvent_getTime(VALUE self)
{
	bz_ListServerUpdateEvent *eventData;

	Data_Get_Struct(self, bz_ListServerUpdateEvent, eventData);
	
	return rb_float_new(eventData->time);
}


//
// bz_BanEventData
// 


VALUE c_ban_event_data_class(void)
{
	return c_ban_event_data;
}

 /* call-seq:
 * 	event_data.banner_id -> Fixnum
 *
 * Returns the player id of the player who issued the ban.
 */

static VALUE 
banEventData_getBannerID(VALUE self)
{
	bz_BanEventData *eventData;

	Data_Get_Struct(self, bz_BanEventData, eventData);

	return INT2FIX(eventData->bannerID);
}

/* call-seq:
 * 	event_data.bannee_id -> Fixnum
 *
 * Returns the player id of the player who got banned.
 */

static VALUE 
banEventData_getBanneeID(VALUE self)
{
	bz_BanEventData *eventData;

	Data_Get_Struct(self, bz_BanEventData, eventData);

	return INT2FIX(eventData->banneeID);
}

/* call-seq:
 * 	event_data.duration -> Float
 *
 * Returns the duration of the ban in minutes. 
 * */

static VALUE 
banEventData_getDuration(VALUE self)
{
	bz_BanEventData *eventData;

	Data_Get_Struct(self, bz_BanEventData, eventData);
	
	return rb_float_new(eventData->duration);
}

/* call-seq:
 * 	event_data.ip_address -> String
 *
 * Returns the ip address which got banned.
 */

static VALUE
banEventData_getIpAddress(VALUE self)
{
	bz_BanEventData *eventData;

	Data_Get_Struct(self, bz_BanEventData, eventData);

	return rb_str_new2(eventData->ipAddress.c_str());
}

/* call-seq:
 * 	event_data.reason -> String
 *
 * Returns the reason of the ban.
 */

static VALUE
banEventData_getReason(VALUE self)
{
	bz_BanEventData *eventData;

	Data_Get_Struct(self, bz_BanEventData, eventData);

	return rb_str_new2(eventData->reason.c_str());
}


//
// bz_HostBanEventData
// 


VALUE c_host_ban_event_data_class(void)
{
	return c_host_ban_event_data;
}

/* call-seq:
 * 	event_data.banner_id -> Fixnum
 *
 * Returns the player id of the player who issued the ban.
 */

static VALUE 
hostBanEventData_getBannerID(VALUE self)
{
	bz_HostBanEventData *eventData;

	Data_Get_Struct(self, bz_HostBanEventData, eventData);

	return INT2FIX(eventData->bannerID);
}

/* call-seq:
 * 	event_data.duration -> Float
 *
 * Returns the duration of the ban in minutes. 
 */

static VALUE 
hostBanEventData_getDuration(VALUE self)
{
	bz_HostBanEventData *eventData;

	Data_Get_Struct(self, bz_HostBanEventData, eventData);
	
	return rb_float_new(eventData->duration);
}

/* call-seq:
 * 	event_data.host_pattern -> String
 *
 * Returns the host pattern which got banned.
 */

static VALUE
hostBanEventData_getHostPattern(VALUE self)
{
	bz_HostBanEventData *eventData;

	Data_Get_Struct(self, bz_HostBanEventData, eventData);

	return rb_str_new2(eventData->hostPattern.c_str());
}

/* call-seq:
 * 	event_data.reason -> String
 *
 * Returns the reason of the ban.
 */

static VALUE
hostBanEventData_getReason(VALUE self)
{
	bz_HostBanEventData *eventData;

	Data_Get_Struct(self, bz_HostBanEventData, eventData);

	return rb_str_new2(eventData->reason.c_str());
}


//
// bz_KickEventData
// 

VALUE c_kick_event_data_class(void)
{
	return c_kick_event_data;
}

/* call-seq:
 * 	event_data.kicker_id -> Fixnum
 *
 * Returns the player id of the player who executed the kick.
 */

static VALUE 
kickEventData_getKickerID(VALUE self)
{
	bz_KickEventData *eventData;

	Data_Get_Struct(self, bz_KickEventData, eventData);

	return INT2FIX(eventData->kickerID);
}

/* call-seq:
 * 	event_data.kicked_id -> Fixnum
 *
 * Returns the player id of the player who got kicked.
 */

static VALUE 
kickEventData_getKickedID(VALUE self)
{
	bz_KickEventData *eventData;

	Data_Get_Struct(self, bz_KickEventData, eventData);

	return INT2FIX(eventData->kickedID);
}

/* call-seq:
 * 	event_data.reason -> String
 *
 * Returns the reason of the kick.
 */

static VALUE
kickEventData_getReason(VALUE self)
{
	bz_KickEventData *eventData;

	Data_Get_Struct(self, bz_KickEventData, eventData);

	return rb_str_new2(eventData->reason.c_str());
}


//
// bz_KillEventData
//

VALUE c_kill_event_data_class(void)
{
	return c_kill_event_data;
}

/* call-seq:
 * 	event_data.killer_id -> Fixnum
 *
 * Returns the player id of the player who made the kill.
 */

static VALUE 
killEventData_getKillerID(VALUE self)
{
	bz_KillEventData *eventData;

	Data_Get_Struct(self, bz_KillEventData, eventData);

	return INT2FIX(eventData->killerID);
}

/* call-seq:
 * 	event_data.killed_id -> Fixnum
 *
 * Returns the player id of the player who got killed.
 */

static VALUE 
killEventData_getKilledID(VALUE self)
{
	bz_KillEventData *eventData;

	Data_Get_Struct(self, bz_KillEventData, eventData);

	return INT2FIX(eventData->killedID);
}

/* call-seq:
 * 	event_data.reason -> String
 *
 * Returns the reason of the kill.
 */

static VALUE
killEventData_getReason(VALUE self)
{
	bz_KillEventData *eventData;

	Data_Get_Struct(self, bz_KillEventData, eventData);

	return rb_str_new2(eventData->reason.c_str());
}


//
// bz_PlayerPausedEventData
//


VALUE c_player_paused_event_data_class(void)
{
	return c_player_paused_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE 
playerPausedEventData_getPlayerID(VALUE self)
{
	bz_PlayerPausedEventData *eventData;

	Data_Get_Struct(self, bz_PlayerPausedEventData, eventData);

	return INT2FIX(eventData->player);
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the player paused.
 */ 

static VALUE 
playerPausedEventData_getTime(VALUE self)
{
	bz_PlayerPausedEventData *eventData;

	Data_Get_Struct(self, bz_PlayerPausedEventData, eventData);
	
	return rb_float_new(eventData->time);
}

/* call-seq:
 *	event_data.paused? -> true or false
 *
 * 	This method returns true if the player is paused, false
 * 	if not paused.
 */ 

static VALUE 
playerPausedEventData_isPaused(VALUE self)
{
	bz_PlayerPausedEventData *eventData;

	Data_Get_Struct(self, bz_PlayerPausedEventData, eventData);
	
	if (eventData->pause)
		return Qtrue;

	return Qfalse;
}


//
// bz_GameStartEndEventData
// 

VALUE c_game_start_end_event_data_class(void)
{
	return c_game_start_end_event_data;
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when game started/ended.
 */ 

static VALUE 
gameStartEndEventData_getTime(VALUE self)
{
	bz_GameStartEndEventData *eventData;

	Data_Get_Struct(self, bz_GameStartEndEventData, eventData);
	
	return rb_float_new(eventData->time);
}

/* call-seq:
 *	event_data.duration -> Float
 *
 * 	This method returns the game duration.
 */ 

static VALUE 
gameStartEndEventData_getDuration(VALUE self)
{
	bz_GameStartEndEventData *eventData;

	Data_Get_Struct(self, bz_GameStartEndEventData, eventData);
	
	return rb_float_new(eventData->duration);
}

//
// bz_SlashCommandEventData
//


VALUE c_slash_command_event_data_class(void)
{
	return c_slash_command_event_data;
}

/* call-seq:
 *	event_data.from -> Fixnum
 *
 * 	This method returns the player id who invoked the slash command.
 */ 

static VALUE 
slashCommandEventData_getFrom(VALUE self)
{
	bz_SlashCommandEventData *eventData;

	Data_Get_Struct(self, bz_SlashCommandEventData, eventData);

	return INT2FIX(eventData->from);
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time a known command was invoked.
 */ 

static VALUE 
slashCommandEventData_getTime(VALUE self)
{
	bz_SlashCommandEventData *eventData;

	Data_Get_Struct(self, bz_SlashCommandEventData, eventData);
	
	return rb_float_new(eventData->time);
}


//
// bz_ServerMsgEventData
//


VALUE c_server_msg_event_data_class(void)
{
	return c_server_msg_event_data;
}

/* call-seq:
 * 	event_data.to -> Fixnum
 *
 * Returns the player id to who the message was sent.
 */

static VALUE 
serverMsgEventData_getTo(VALUE self)
{
	bz_ServerMsgEventData *eventData;

	Data_Get_Struct(self, bz_ServerMsgEventData, eventData);

	return INT2FIX(eventData->to);
}

/* call-seq:
 * 	event_data.team -> Fixnum
 *
 * Returns the team of the player who invoked the event.
 */

static VALUE
serverMsgEventData_getTeam(VALUE self)
{
	bz_ServerMsgEventData *eventData;

	Data_Get_Struct(self, bz_ServerMsgEventData, eventData);

	return INT2FIX(eventData->team);
}

/* call-seq:
 * 	event_data.message -> String
 *
 * Returns the server message.
 */

static VALUE
serverMsgEventData_getMessage(VALUE self)
{
	bz_ServerMsgEventData *eventData;

	Data_Get_Struct(self, bz_ServerMsgEventData, eventData);

	return rb_str_new2(eventData->message.c_str());
}

/* call-seq:
 *	event_data.time -> Float
 *
 * 	This method returns the time when the event was invoked.
 */ 

static VALUE 
serverMsgEventData_getTime(VALUE self)
{
	bz_ServerMsgEventData *eventData;

	Data_Get_Struct(self, bz_ServerMsgEventData, eventData);
	
	return rb_float_new(eventData->time);
}


//
// bz_ShotFiredEventData
// 


VALUE c_shot_fired_event_data_class(void)
{
	return c_shot_fired_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE
shotFiredEventData_getPlayerID(VALUE self)
{
	bz_ShotFiredEventData *eventData;

	Data_Get_Struct(self, bz_ShotFiredEventData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 *	event_data.pos -> Array
 *
 * 	This method returns the position where shot originated from.
 */ 

static VALUE
shotFiredEventData_getPos(VALUE self)
{
	bz_ShotFiredEventData *eventData;

	Data_Get_Struct(self, bz_ShotFiredEventData, eventData);

	VALUE pos = rb_ary_new();

	rb_ary_push(pos, rb_float_new(eventData->pos[0]));
	rb_ary_push(pos, rb_float_new(eventData->pos[1]));
	rb_ary_push(pos, rb_float_new(eventData->pos[2]));

	return pos;
}

/* call-seq:
 * 	event_data.type -> String
 *
 * Returns the type of the fired shot
 */

static VALUE
shotFiredEventData_getType(VALUE self)
{
	bz_ShotFiredEventData *eventData;

	Data_Get_Struct(self, bz_ShotFiredEventData, eventData);

	return rb_str_new2(eventData->type.c_str());
}

/* call-seq:
 * 	event_data.type=(String type) -> String
 *
 * Sets the type of the fired shot
 */


static VALUE
shotFiredEventData_setType(VALUE self, VALUE type)
{
	bz_ShotFiredEventData *eventData;

	Data_Get_Struct(self, bz_ShotFiredEventData, eventData);

	eventData->type = RSTRING(StringValue(type))->ptr;

	return self;
}

/* call-seq:
 * 	event_data.changed? -> true or false
 *
 * Returns true if ... , false if not changed  (todo)
 */

static VALUE 
shotFiredEventData_isChanged(VALUE self)
{
	bz_ShotFiredEventData *eventData;

	Data_Get_Struct(self, bz_ShotFiredEventData, eventData);
	
	if (eventData->changed)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 * 	event_data.changed=(true or false) -> self
 *
 * Sets ... (todo)
 */

static VALUE 
shotFiredEventData_setChanged(VALUE self, VALUE changed)
{
	bz_ShotFiredEventData *eventData;

	Data_Get_Struct(self, bz_ShotFiredEventData, eventData);

	switch (TYPE(changed)) 
	{
     case T_TRUE:
		eventData->changed=true;
		break;
	case T_FALSE:
		eventData->changed=false;
		break;
	default:
		rb_raise(rb_eTypeError, "not valid value");
		break;
	}
	
	return self;
}


//
// bz_ShotEndedEventData
// 

VALUE c_shot_ended_event_data_class(void)
{
	return c_shot_ended_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE
shotEndedEventData_getPlayerID(VALUE self)
{
	bz_ShotEndedEventData *eventData;

	Data_Get_Struct(self, bz_ShotEndedEventData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 * 	event_data.shot_id -> Fixnum
 *
 * Returns the shot id of the ended shot
 */

static VALUE
shotEndedEventData_getShotID(VALUE self)
{
	bz_ShotEndedEventData *eventData;

	Data_Get_Struct(self, bz_ShotEndedEventData, eventData);

	return INT2FIX(eventData->shotID);
}

/* call-seq:
 * 	event_data.explode? -> true or false
 *
 * Returns true if the ended shot is exploded, false when not.
 */

static VALUE 
shotEndedEventData_isExplode(VALUE self)
{
	bz_ShotEndedEventData *eventData;

	Data_Get_Struct(self, bz_ShotEndedEventData, eventData);
	
	if (eventData->explode)
		return Qtrue;

	return Qfalse;
}


//
// bz_FlagGrabbedEventData
//


VALUE c_flag_grabbed_event_data_class(void)
{
	return c_flag_grabbed_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE
flagGrabbedEventData_getPlayerID(VALUE self)
{
	bz_FlagGrabbedEventData *eventData;

	Data_Get_Struct(self, bz_FlagGrabbedEventData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 * 	event_data.flag_id -> Fixnum
 *
 * Returns the flag id of the grabbed flag
 */

static VALUE
flagGrabbedEventData_getFlagID(VALUE self)
{
	bz_FlagGrabbedEventData *eventData;

	Data_Get_Struct(self, bz_FlagGrabbedEventData, eventData);

	return INT2FIX(eventData->flagID);
}

/* call-seq:
 * 	event_data.flag_type -> String
 *
 * Returns the flag type of the grabbed flag
 */

static VALUE
flagGrabbedEventData_getFlagType(VALUE self)
{
	bz_FlagGrabbedEventData *eventData;

	Data_Get_Struct(self, bz_FlagGrabbedEventData, eventData);

	return rb_str_new2(eventData->flagType);
}

/* call-seq:
 *	event_data.pos -> Array
 *
 * 	This method returns the position of the grabbed flag.
 */ 

static VALUE 
flagGrabbedEventData_getPos(VALUE self)
{
	bz_FlagGrabbedEventData *eventData;

	Data_Get_Struct(self, bz_FlagGrabbedEventData, eventData);

	VALUE pos = rb_ary_new();

	rb_ary_push(pos, rb_float_new(eventData->pos[0]));
	rb_ary_push(pos, rb_float_new(eventData->pos[1]));
	rb_ary_push(pos, rb_float_new(eventData->pos[2]));

	return pos;
}

//
// bz_FlagDroppedEventData
//

VALUE c_flag_dropped_event_data_class(void)
{
	return c_flag_dropped_event_data;
}

/* call-seq:
 * 	event_data.player_id -> Fixnum
 *
 * Returns the player id of the player who invoked the event.
 */

static VALUE
flagDroppedEventData_getPlayerID(VALUE self)
{
	bz_FlagDroppedEventData *eventData;

	Data_Get_Struct(self, bz_FlagDroppedEventData, eventData);

	return INT2FIX(eventData->playerID);
}

/* call-seq:
 * 	event_data.flag_id -> Fixnum
 *
 * Returns the flag id of the dropped flag
 */

static VALUE
flagDroppedEventData_getFlagID(VALUE self)
{
	bz_FlagDroppedEventData *eventData;

	Data_Get_Struct(self, bz_FlagDroppedEventData, eventData);

	return INT2FIX(eventData->flagID);
}

/* call-seq:
 * 	event_data.flag_type -> String
 *
 * Returns the flag type of the dropped flag
 */

static VALUE
flagDroppedEventData_getFlagType(VALUE self)
{
	bz_FlagDroppedEventData *eventData;

	Data_Get_Struct(self, bz_FlagDroppedEventData, eventData);

	return rb_str_new2(eventData->flagType);
}

/* call-seq:
 *	event_data.pos -> Array
 *
 * 	This method returns the position where the flag got dropped.
 */ 

static VALUE 
flagDroppedEventData_getPos(VALUE self)
{
	bz_FlagDroppedEventData *eventData;

	Data_Get_Struct(self, bz_FlagDroppedEventData, eventData);

	VALUE pos = rb_ary_new();

	rb_ary_push(pos, rb_float_new(eventData->pos[0]));
	rb_ary_push(pos, rb_float_new(eventData->pos[1]));
	rb_ary_push(pos, rb_float_new(eventData->pos[2]));

	return pos;
}


//
// class bz_PlayerRecord
//

VALUE c_player_record_class(void)
{
        return c_player_record;
}

void playerRecord_free(bz_PlayerRecord * playerRecord)
{

	bz_freePlayerRecord(playerRecord);
}

static VALUE
playerRecord_alloc(VALUE klass)
{

	VALUE obj;

	bz_PlayerRecord *playerRecord = new bz_PlayerRecord();

	obj= Data_Wrap_Struct(klass, 0, playerRecord_free, playerRecord);

	return obj;

}

/* call-seq:
 * 	Player.new(player_id) -> Player object
 *
 * This method returns a player object from the given player id.
 */

static VALUE 
playerRecord_initialize(VALUE self, VALUE playerID)
{
	VALUE obj;

	bz_PlayerRecord *curPlayerRecord = bz_getPlayerByIndex(FIX2INT(playerID));
	bz_PlayerRecord *playerRecord; 

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	playerRecord->playerID = curPlayerRecord->playerID;
	playerRecord->callsign = curPlayerRecord->callsign;
	playerRecord->email = curPlayerRecord->email;
	playerRecord->team = curPlayerRecord->team;
	memcpy(playerRecord->pos, curPlayerRecord->pos, sizeof(float) * 3);
	playerRecord->rot = curPlayerRecord->rot;
	playerRecord->ipAddress = curPlayerRecord->ipAddress;
	playerRecord->currentFlag = curPlayerRecord->currentFlag;
	playerRecord->flagHistory = curPlayerRecord->flagHistory;
	playerRecord->spawned = curPlayerRecord->spawned;
	playerRecord->verified = curPlayerRecord->verified;
	playerRecord->globalUser = curPlayerRecord->globalUser;
	playerRecord->admin = curPlayerRecord->admin;
	playerRecord->op = curPlayerRecord->op;
	playerRecord->groups = curPlayerRecord->groups;
	playerRecord->lag = curPlayerRecord->lag;
	playerRecord->wins = curPlayerRecord->wins;
	playerRecord->losses = curPlayerRecord->losses;
	playerRecord->teamKills = curPlayerRecord->teamKills;

	delete curPlayerRecord;

	return self;
}

/* call-seq:
 * 	player.player_id -> Fixnum
 *
 * This method returns the player id of the player.
 */

static VALUE 
playerRecord_getPlayerID(VALUE self)
{
    bz_PlayerRecord *playerRecord;

    Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return INT2FIX(playerRecord->playerID);
}

/* call-seq:
 * 	player.callsign -> String
 *
 * This method returns the callsign of the player.
 */

static VALUE
playerRecord_getCallsign(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return rb_str_new2(playerRecord->callsign.c_str());

}

/* call-seq:
 * 	player.email -> String
 *
 * This method returns the email of the player.
 */

static VALUE
playerRecord_getEmail(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return rb_str_new2(playerRecord->email.c_str());

}

/* call-seq:
 * 	player.team -> Fixnum
 *
 * This method returns the team of the player.
 */

static VALUE 
playerRecord_getTeam(VALUE self)
{

    bz_PlayerRecord *playerRecord;

    Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return INT2FIX(playerRecord->team);
}

/* call-seq:
 *	player.pos -> Array
 *
 * 	This method returns the current position of the player.
 */ 

static VALUE 
playerRecord_getPos(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	VALUE pos = rb_ary_new();

	rb_ary_push(pos, rb_float_new(playerRecord->pos[0]));
	rb_ary_push(pos, rb_float_new(playerRecord->pos[1]));
	rb_ary_push(pos, rb_float_new(playerRecord->pos[2]));

	return pos;
}

/* call-seq:
 *	player.rot -> Float
 *
 * 	This method returns the current rotation angle of the player.
 */ 

static VALUE
playerRecord_getRot(VALUE self)
{

    bz_PlayerRecord *playerRecord;

    Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return rb_float_new(playerRecord->rot);
}

/* call-seq:
 * 	event_data.ip_address -> String
 *
 * Returns the ip address which got banned.
 */

static VALUE
playerRecord_getIpAddress(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return rb_str_new2(playerRecord->ipAddress.c_str());

}

/* call-seq:
 *	player.current_flag -> String
 *
 * 	This method returns the current flag of the player.
 */ 

static VALUE
playerRecord_getCurrentFlag(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return rb_str_new2(playerRecord->currentFlag.c_str());

}

/* call-seq:
 *	player.flag_history -> Array
 *
 * 	This method returns the flag history list of a player
 */ 

static VALUE
playerRecord_getFlagHistory(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	VALUE flagHistory = rb_ary_new();

	for (int i = 0; i <  playerRecord->flagHistory.size(); i++)
		rb_ary_push(flagHistory, rb_str_new2(playerRecord->flagHistory[i].c_str()));

	return flagHistory;

}

/* call-seq:
 *	player.spawned? -> true or false
 *
 * 	This method returns true if the player is spawned, else it returns
 * 	false
 */ 

static VALUE 
playerRecord_isSpawned(VALUE self)
{
	
	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);
	
	if (playerRecord->spawned)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	player.verified? -> true or false
 *
 * 	This method returns true if the player is verified, else it returns
 * 	false
 */ 

static VALUE 
playerRecord_isVerified(VALUE self)
{
	
	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);
	
	if (playerRecord->verified)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	player.global_user? -> true or false
 *
 * 	This method returns true if the player is a global user, else it 
 * 	returns	false
 */ 

static VALUE 
playerRecord_isGlobalUser(VALUE self)
{
	
	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);
	
	if (playerRecord->globalUser)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	player.bz_id -> String
 *
 * 	This method returns the bz id of the player
 */ 

static VALUE
playerRecord_getBzID(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return rb_str_new2(playerRecord->bzID.c_str());

}

/* call-seq:
 *	player.admin? -> true or false
 *
 * 	This method returns true if the player is an admin, else it 
 * 	returns	false
 */ 

static VALUE 
playerRecord_isAdmin(VALUE self)
{
	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);
	
	if (playerRecord->admin)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	player.op? -> true or false
 *
 * 	This method returns true if the player is an operator, else it 
 * 	returns	false
 */ 

static VALUE 
playerRecord_isOp(VALUE self)
{
	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);
	
	if (playerRecord->op)
		return Qtrue;

	return Qfalse;
}

/* call-seq:
 *	player.groups -> Array
 *
 * 	This method returns a list of groups where the player is in
 */ 

static VALUE
playerRecord_getGroups(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	VALUE groups = rb_ary_new();

	for (int i = 0; i <  playerRecord->groups.size(); i++)
		rb_ary_push(groups, rb_str_new2(playerRecord->groups[i].c_str()));

	return groups;

}

/* call-seq:
 *	player.lag -> Fixnum
 *
 * 	This method returns the lag value of the player
 */ 

static VALUE
playerRecord_getLag(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return INT2FIX(playerRecord->lag);

}

/* call-seq:
 *	player.wins -> Fixnum
 *
 * 	This method returns the win value of the player
 */ 

static VALUE
playerRecord_getWins(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return INT2FIX(playerRecord->wins);

}

/* call-seq:
 *	player.losses -> Fixnum
 *
 * 	This method returns the losses value of the player
 */ 

static VALUE
playerRecord_getLosses(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return INT2FIX(playerRecord->losses);

}

/* call-seq:
 *	player.lag -> Fixnum
 *
 * 	This method returns the teamkill value of the player
 */ 

static VALUE
playerRecord_getTeamKills(VALUE self)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	return INT2FIX(playerRecord->teamKills);

}

/* call-seq:
 *	player.has_perm? -> true or false
 *
 * 	This method returns true if the player has the given perm,
 * 	else itreturnsfalse
 */ 

static VALUE
playerRecord_isHasPerm(VALUE self, VALUE perm)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	if (bz_hasPerm(playerRecord->playerID, RSTRING(StringValue(perm))->ptr))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	player.grant_perm(String perm) -> true or false
 *
 * 	This method grants the specified perm to the player and
 * 	returns true on success, false if unsuccesfull.
 */ 

static VALUE
playerRecord_setGrantPerm(VALUE self, VALUE perm)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	if (bz_grantPerm(playerRecord->playerID, RSTRING(StringValue(perm))->ptr))
		return Qtrue;

	return Qfalse;

}

/* call-seq:
 *	player.revoke_perm(String perm) -> true or false
 *
 * 	This method revokes the specified perm to the player and
 * 	returns true on success, false if unsuccesfull.
 */ 

static VALUE
playerRecord_setRevokePerm(VALUE self, VALUE perm)
{

	bz_PlayerRecord *playerRecord;

	Data_Get_Struct(self, bz_PlayerRecord, playerRecord);

	if (bz_revokePerm(playerRecord->playerID, RSTRING(StringValue(perm))->ptr))
		return Qtrue;

	return Qfalse;

}

static VALUE
bzflag_bz_getWorldCacheData(VALUE self)
{
  unsigned int size = bz_getWorldCacheSize();
  
  char *database = new char[size];
  unsigned int read = bz_getWorldCacheData((unsigned char*)database);
  
  VALUE ruby_string = rb_str_new(database, size);
	
  return ruby_string;
}


static VALUE
bzflag_bz_killPlayer(VALUE self, VALUE playerID, VALUE killerID)
{
  bool killed = bz_killPlayer(FIX2INT(playerID), true, FIX2INT(killerID));
  if ( killed) 
   return Qtrue;
 
  return Qfalse;
}


void InitPlugin(void)
{

	// ***  Observations ***
	// * To make sure you don't have to use Bzflag:: to bring the module
	//   vars/methods in scope use the include directive in the ruby file
	// * Constant vars must start with an uppercase character
	// * The bz event enum should probably not be translated to ruby
	//   constants

	// define module Bzflag
	bzflag_module = rb_define_module("Bzflag");

	// define module constants
	
	rb_define_const(bzflag_module,"BZ_eNullEvent", INT2FIX(bz_eNullEvent));
	rb_define_const(bzflag_module,"BZ_eCaptureEvent", INT2FIX(bz_eCaptureEvent));
	rb_define_const(bzflag_module,"BZ_ePlayerDieEvent", INT2FIX(bz_ePlayerDieEvent));
	rb_define_const(bzflag_module,"BZ_ePlayerSpawnEvent", INT2FIX(bz_ePlayerSpawnEvent));
	rb_define_const(bzflag_module,"BZ_eZoneEntryEvent", INT2FIX(bz_ePlayerSpawnEvent));
	rb_define_const(bzflag_module,"BZ_eZoneExitEvent", INT2FIX(bz_eZoneExitEvent));
	rb_define_const(bzflag_module,"BZ_ePlayerJoinEvent", INT2FIX(bz_ePlayerJoinEvent));
	rb_define_const(bzflag_module,"BZ_ePlayerPartEvent", INT2FIX(bz_ePlayerPartEvent));
	rb_define_const(bzflag_module,"BZ_eChatMessageEvent", INT2FIX(bz_eChatMessageEvent));
	rb_define_const(bzflag_module,"BZ_eUnknownSlashCommand", INT2FIX(bz_eUnknownSlashCommand));
	rb_define_const(bzflag_module,"BZ_eGetPlayerSpawnPosEvent", INT2FIX(bz_eGetPlayerSpawnPosEvent));
	rb_define_const(bzflag_module,"BZ_eGetAutoTeamEvent", INT2FIX(bz_eGetAutoTeamEvent));
	rb_define_const(bzflag_module,"BZ_eAllowPlayer", INT2FIX(bz_eAllowPlayer));
	rb_define_const(bzflag_module,"BZ_eTickEvent", INT2FIX(bz_eTickEvent));
	rb_define_const(bzflag_module,"BZ_eGetWorldEvent", INT2FIX(bz_eGetWorldEvent));
	rb_define_const(bzflag_module,"BZ_eGetPlayerInfoEvent", INT2FIX(bz_eGetPlayerInfoEvent));
	rb_define_const(bzflag_module,"BZ_eAllowSpawn", INT2FIX(bz_eAllowSpawn));
	rb_define_const(bzflag_module,"BZ_eListServerUpdateEvent", INT2FIX(bz_eListServerUpdateEvent));
	rb_define_const(bzflag_module,"BZ_eBanEvent", INT2FIX(bz_eBanEvent));
	rb_define_const(bzflag_module,"BZ_eHostBanEvent", INT2FIX(bz_eHostBanEvent));
	rb_define_const(bzflag_module,"BZ_eKickEvent", INT2FIX(bz_eKickEvent));
	rb_define_const(bzflag_module,"BZ_eKillEvent", INT2FIX(bz_eKillEvent));
	rb_define_const(bzflag_module,"BZ_ePlayerPausedEvent", INT2FIX(bz_ePlayerPausedEvent));
	rb_define_const(bzflag_module,"BZ_eMessagFilteredEvent", INT2FIX(bz_eMessageFilteredEvent));
	rb_define_const(bzflag_module,"BZ_eGameStartEvent", INT2FIX(bz_eGameStartEvent));
	rb_define_const(bzflag_module,"BZ_eGameEndEvent", INT2FIX(bz_eGameEndEvent));
	rb_define_const(bzflag_module,"BZ_eSlashCommandEvent", INT2FIX(bz_eSlashCommandEvent));
	rb_define_const(bzflag_module,"BZ_ePlayerAuthEvent", INT2FIX(bz_ePlayerAuthEvent));
	rb_define_const(bzflag_module,"BZ_eServerMsgEvent", INT2FIX(bz_eServerMsgEvent));
	rb_define_const(bzflag_module,"BZ_eShotFiredEvent", INT2FIX(bz_eShotFiredEvent));
	rb_define_const(bzflag_module,"BZ_ePlayerUpdateEvent", INT2FIX(bz_ePlayerUpdateEvent));
	rb_define_const(bzflag_module,"BZ_eNetDataSendEvent", INT2FIX(bz_eNetDataSendEvent));
	rb_define_const(bzflag_module,"BZ_eNetDataReceveEvent", INT2FIX(bz_eNetDataReceveEvent));
	rb_define_const(bzflag_module,"BZ_eLogingEvent", INT2FIX(bz_eLogingEvent));
	rb_define_const(bzflag_module,"BZ_eShotEndedEvent", INT2FIX(bz_eShotEndedEvent));
	rb_define_const(bzflag_module,"BZ_eFlagTransferredEvent", INT2FIX(bz_eFlagTransferredEvent));
	rb_define_const(bzflag_module,"BZ_eFlagGrabbedEvent", INT2FIX(bz_eFlagGrabbedEvent));
	rb_define_const(bzflag_module,"BZ_eFlagDroppedEvent", INT2FIX(bz_eFlagDroppedEvent));

	rb_define_const(bzflag_module,"BZ_eLastEvent" , INT2FIX(bz_eLastEvent));


	// BZFlag user constants
	rb_define_const(bzflag_module,"BZ_SERVER", INT2FIX(BZ_SERVER));
	rb_define_const(bzflag_module,"BZ_ALLUSERS", INT2FIX(BZ_ALLUSERS));
	rb_define_const(bzflag_module,"BZ_NULLUSER", INT2FIX(BZ_NULLUSER));

	// BZFlag team constants


	rb_define_const(bzflag_module,"NoTeam",INT2FIX(eNoTeam));
	rb_define_const(bzflag_module,"RogueTeam",INT2FIX(eRogueTeam));
	rb_define_const(bzflag_module,"RedTeam",INT2FIX(eRedTeam));
	rb_define_const(bzflag_module,"GreenTeam",INT2FIX(eGreenTeam));
	rb_define_const(bzflag_module,"BlueTeam",INT2FIX(eBlueTeam));
	rb_define_const(bzflag_module,"PurpleTeam",INT2FIX(ePurpleTeam));
	rb_define_const(bzflag_module,"RabbitTeam",INT2FIX(eRabbitTeam));
	rb_define_const(bzflag_module,"HunterTeam",INT2FIX(eHunterTeam));
	rb_define_const(bzflag_module,"Observers",INT2FIX(eObservers));
	rb_define_const(bzflag_module,"Administrators",INT2FIX(eAdministrators));

	//
	// module methods
	//

	rb_define_module_function(bzflag_module,"bz_send_text_message", VALUEFUNC(bzflag_bz_sendTextMessage), 3); 

	rb_define_module_function(bzflag_module,"bz_get_player_index_list", VALUEFUNC(bzflag_bz_getPlayerIndexList), 0); 
	rb_define_module_function(bzflag_module,"bz_has_perm?", VALUEFUNC(bzflag_bz_hasPerm), 2); 
	rb_define_module_function(bzflag_module,"bz_grant_perm", VALUEFUNC(bzflag_bz_grantPerm), 2); 
	rb_define_module_function(bzflag_module,"bz_revoke_perm", VALUEFUNC(bzflag_bz_revokePerm), 2); 

	rb_define_module_function(bzflag_module,"bz_is_player_paused?", VALUEFUNC(bzflag_bz_isPlayerPaused), 1); 

	rb_define_module_function(bzflag_module,"bz_get_player_flag", VALUEFUNC(bzflag_bz_getPlayerFlag), 1); 
	
	rb_define_module_function(bzflag_module,"bz_get_world_cache_data", VALUEFUNC(bzflag_bz_getWorldCacheData), 0); 
	
	rb_define_module_function(bzflag_module,"bz_kill_player", VALUEFUNC(bzflag_bz_killPlayer), 2);
	

	// player lag info
	rb_define_module_function(bzflag_module,"bz_get_player_lag", VALUEFUNC(bzflag_bz_getPlayerLag), 1); 
	rb_define_module_function(bzflag_module,"bz_get_player_jitter", VALUEFUNC(bzflag_bz_getPlayerJitter), 1); 
	rb_define_module_function(bzflag_module,"bz_get_player_packetloss", VALUEFUNC(bzflag_bz_getPlayerPacketloss), 1); 
	

	rb_define_module_function(bzflag_module,"bz_reset_player_score", VALUEFUNC(bzflag_bz_resetPlayerScore), 1); 
	rb_define_module_function(bzflag_module,"bz_set_player_operator", VALUEFUNC(bzflag_bz_setPlayerOperator), 1); 
	rb_define_module_function(bzflag_module,"bz_get_team_player_limit", VALUEFUNC(bzflag_bz_getTeamPlayerLimit), 1); 

	rb_define_module_function(bzflag_module,"bz_get_group_list", VALUEFUNC(bzflag_bz_getGroupList), 0); 
	rb_define_module_function(bzflag_module,"bz_get_group_perms", VALUEFUNC(bzflag_bz_getGroupPerms), 1); 
	rb_define_module_function(bzflag_module,"bz_group_allow_perm", VALUEFUNC(bzflag_bz_groupAllowPerm), 2); 


	rb_define_module_function(bzflag_module,"bz_sent_fetch_res_message", VALUEFUNC(bzflag_bz_sentFetchResMessage), 2); 


	// logging
	
	rb_define_module_function(bzflag_module,"bz_debug_message", VALUEFUNC(bzflag_bz_debugMessage), 2); 
	rb_define_module_function(bzflag_module,"bz_get_debug_level", VALUEFUNC(bzflag_bz_getDebugLevel), 0); 

	rb_define_module_function(bzflag_module,"bz_kick_user", VALUEFUNC(bzflag_bz_kickUser), 3); 
	rb_define_module_function(bzflag_module,"bz_ip_ban_user", VALUEFUNC(bzflag_bz_IPBanUser), 4); 
	rb_define_module_function(bzflag_module,"bz_ip_unban_user", VALUEFUNC(bzflag_bz_IPUnbanUser), 1); 
	
	rb_define_module_function(bzflag_module,"bz_get_reports", VALUEFUNC(bzflag_bz_getReports), 0); 

	// timelimit

	rb_define_module_function(bzflag_module,"bz_set_time_limit", VALUEFUNC(bzflag_bz_setTimeLimit), 1); 
	rb_define_module_function(bzflag_module,"bz_get_time_limit", VALUEFUNC(bzflag_bz_getTimeLimit), 0); 
	rb_define_module_function(bzflag_module,"bz_is_time_manual_start?", VALUEFUNC(bzflag_bz_isTimeManualStart), 0); 
	rb_define_module_function(bzflag_module,"bz_is_count_down_active?", VALUEFUNC(bzflag_bz_isCountDownActive), 0); 
	rb_define_module_function(bzflag_module,"bz_is_count_down_in_progress?", VALUEFUNC(bzflag_bz_isCountDownInProgress), 0); 

	//
	//define superclass Plugin
	//

	plugin = rb_define_class_under(bzflag_module,"Plugin",rb_cObject); 

	//rb_define_method(plugin, "registerEvent", VALUEFUNC(plugin_registerEvent), 2);
	rb_define_method(plugin, "register", VALUEFUNC(plugin_register), 0);

	// class bz_PlayerRecord

	c_player_record = rb_define_class_under(bzflag_module, "Player", rb_cObject);
	rb_define_method(c_player_record, "initialize", VALUEFUNC(playerRecord_initialize), 1);
	rb_define_method(c_player_record, "player_id", VALUEFUNC(playerRecord_getPlayerID), 0);
	rb_define_method(c_player_record, "callsign", VALUEFUNC(playerRecord_getCallsign), 0);
	rb_define_method(c_player_record, "email", VALUEFUNC(playerRecord_getEmail), 0);
	rb_define_method(c_player_record, "team", VALUEFUNC(playerRecord_getTeam), 0);
	rb_define_method(c_player_record, "pos", VALUEFUNC(playerRecord_getPos), 0);
	rb_define_method(c_player_record, "rot", VALUEFUNC(playerRecord_getRot), 0);
	rb_define_method(c_player_record, "ip_address", VALUEFUNC(playerRecord_getIpAddress), 0);
	rb_define_method(c_player_record, "current_flag", VALUEFUNC(playerRecord_getCurrentFlag), 0);
	rb_define_method(c_player_record, "flag_history", VALUEFUNC(playerRecord_getFlagHistory), 0);
	rb_define_method(c_player_record, "spawned?", VALUEFUNC(playerRecord_isSpawned), 0);
	rb_define_method(c_player_record, "verified?", VALUEFUNC(playerRecord_isVerified), 0);
	rb_define_method(c_player_record, "global_user?", VALUEFUNC(playerRecord_isGlobalUser), 0);
	rb_define_method(c_player_record, "bz_id", VALUEFUNC(playerRecord_getBzID), 0);
	rb_define_method(c_player_record, "admin?", VALUEFUNC(playerRecord_isAdmin), 0);
	rb_define_method(c_player_record, "op?", VALUEFUNC(playerRecord_isOp), 0);
	rb_define_method(c_player_record, "groups", VALUEFUNC(playerRecord_getGroups), 0);
	rb_define_method(c_player_record, "lag", VALUEFUNC(playerRecord_getLag), 0);
	rb_define_method(c_player_record, "wins", VALUEFUNC(playerRecord_getWins), 0);
	rb_define_method(c_player_record, "losses", VALUEFUNC(playerRecord_getLosses), 0);
	rb_define_method(c_player_record, "team_kills", VALUEFUNC(playerRecord_getTeamKills), 0);

	//rb_define_method(c_player_record, "update", VALUEFUNC(playerRecord_doUpdate), 1);
	rb_define_method(c_player_record, "has_perm?", VALUEFUNC(playerRecord_isHasPerm), 1);
	rb_define_method(c_player_record, "grant_perm", VALUEFUNC(playerRecord_setGrantPerm), 1);
	rb_define_method(c_player_record, "revoke_perm", VALUEFUNC(playerRecord_setRevokePerm), 1);

	rb_define_alloc_func(c_player_record, playerRecord_alloc);

	//
	// event classes
	//

	// bz_EventData 

	c_event_data = rb_define_class_under(bzflag_module,"EventData", rb_cObject);
	rb_define_method(c_event_data, "event_type", VALUEFUNC(eventData_eventType), 0);

	// bz_CTFCaptureEventData

	c_ctf_capture_event_data = rb_define_class_under(bzflag_module,"CTFCaptureEventData",  c_event_data);
	rb_define_method(c_ctf_capture_event_data, "team_capped", VALUEFUNC(cTFCaptureEventData_getTeamCapped), 0);
	rb_define_method(c_ctf_capture_event_data, "team_capping", VALUEFUNC(cTFCaptureEventData_getTeamCapping), 0);
	rb_define_method(c_ctf_capture_event_data, "player_capping", VALUEFUNC(cTFCaptureEventData_getPlayerCapping), 0);
	rb_define_method(c_ctf_capture_event_data, "pos", VALUEFUNC(cTFCaptureEventData_getPos), 0);
	rb_define_method(c_ctf_capture_event_data, "rot", VALUEFUNC(cTFCaptureEventData_getRot), 0);
	rb_define_method(c_ctf_capture_event_data, "time", VALUEFUNC(cTFCaptureEventData_getTime), 0);
	
	// bz_PlayerDieEventData
	c_player_die_event_data = rb_define_class_under(bzflag_module,"PlayerDieEventData", c_event_data);
	rb_define_method(c_player_die_event_data, "player_id", VALUEFUNC(playerDieEventData_getPlayerID), 0);
	rb_define_method(c_player_die_event_data, "team", VALUEFUNC(playerDieEventData_getTeam), 0);
	rb_define_method(c_player_die_event_data, "killer_id", VALUEFUNC(playerDieEventData_getKillerID), 0);
	rb_define_method(c_player_die_event_data, "killer_team", VALUEFUNC(playerDieEventData_getKillerTeam), 0);
	rb_define_method(c_player_die_event_data, "flag_killed_with", VALUEFUNC(playerDieEventData_getFlagKilledWith), 0);
	rb_define_method(c_player_die_event_data, "shot_id", VALUEFUNC(playerDieEventData_getShotID), 0);
	rb_define_method(c_player_die_event_data, "pos", VALUEFUNC(playerDieEventData_getPos), 0);
	rb_define_method(c_player_die_event_data, "rot", VALUEFUNC(playerDieEventData_getRot), 0);
	rb_define_method(c_player_die_event_data, "time", VALUEFUNC(playerDieEventData_getTime), 0);

	// bz_PlayerSpawnEventData
	c_player_spawn_event_data = rb_define_class_under(bzflag_module,"PlayerSpawnEventData", c_event_data);
	rb_define_method(c_player_spawn_event_data, "player_id", VALUEFUNC(playerSpawnEventData_getPlayerID), 0);
	rb_define_method(c_player_spawn_event_data, "team", VALUEFUNC(playerSpawnEventData_getTeam), 0);
	rb_define_method(c_player_spawn_event_data, "pos", VALUEFUNC(playerSpawnEventData_getPos), 0);
	rb_define_method(c_player_spawn_event_data, "rot", VALUEFUNC(playerSpawnEventData_getRot), 0);
	rb_define_method(c_player_spawn_event_data, "time", VALUEFUNC(playerSpawnEventData_getTime), 0);


	// bz_ChatEventData
	c_chat_event_data = rb_define_class_under(bzflag_module,"ChatEventData", c_event_data);
    rb_define_method(c_chat_event_data, "from", VALUEFUNC(chatEventData_getFrom), 0);
    rb_define_method(c_chat_event_data, "to", VALUEFUNC(chatEventData_getTo), 0);
    rb_define_method(c_chat_event_data, "team", VALUEFUNC(chatEventData_getTeam), 0);
    rb_define_method(c_chat_event_data, "message", VALUEFUNC(chatEventData_getMessage), 0);
    rb_define_method(c_chat_event_data, "time", VALUEFUNC(chatEventData_getTime), 0);

	// bz_PlayerJoinPartEventData

	c_player_join_part_event_data = rb_define_class_under(bzflag_module,"PlayerJoinPartEventData", c_event_data);
	rb_define_method(c_player_join_part_event_data, "player_id", VALUEFUNC(playerJoinPartEventData_getPlayerID), 0);
	rb_define_method(c_player_join_part_event_data, "team", VALUEFUNC(playerJoinPartEventData_getTeam), 0);
	rb_define_method(c_player_join_part_event_data, "callsign", VALUEFUNC(playerJoinPartEventData_getCallsign), 0);
	rb_define_method(c_player_join_part_event_data, "email", VALUEFUNC(playerJoinPartEventData_getEmail), 0);
	rb_define_method(c_player_join_part_event_data, "verified?", VALUEFUNC(playerJoinPartEventData_isVerified), 0);
	rb_define_method(c_player_join_part_event_data, "global_user", VALUEFUNC(playerJoinPartEventData_getGlobalUser), 0);
	rb_define_method(c_player_join_part_event_data, "ip_address", VALUEFUNC(playerJoinPartEventData_getIpAddress), 0);
	rb_define_method(c_player_join_part_event_data, "reason", VALUEFUNC(playerJoinPartEventData_getReason), 0);
	rb_define_method(c_player_join_part_event_data, "time", VALUEFUNC(playerJoinPartEventData_getTime), 0);

	// bz_UnknownSlashCommandEventData
	c_unknown_slash_command_event_data = rb_define_class_under(bzflag_module,"UnknownSlashCommandEventData", c_event_data);
	rb_define_method(c_unknown_slash_command_event_data, "from", VALUEFUNC(unknownSlashCommandEventData_getFrom), 0);
	rb_define_method(c_unknown_slash_command_event_data, "message", VALUEFUNC(unknownSlashCommandEventData_getMessage), 0);
	rb_define_method(c_unknown_slash_command_event_data, "handled?", VALUEFUNC(unknownSlashCommandEventData_isHandled), 0);
	rb_define_method(c_unknown_slash_command_event_data, "handled=", VALUEFUNC(unknownSlashCommandEventData_setHandled), 1);
	rb_define_method(c_unknown_slash_command_event_data, "time", VALUEFUNC(unknownSlashCommandEventData_getTime), 0);

	// bz_GetPlayerSpawnPosEventData
	c_get_player_spawn_pos_event_data = rb_define_class_under(bzflag_module,"GetPlayerSpawnPosEventData", c_event_data);
	rb_define_method(c_get_player_spawn_pos_event_data, "player_id", VALUEFUNC(getPlayerSpawnPosEventData_getPlayerID), 0);
	rb_define_method(c_get_player_spawn_pos_event_data, "team", VALUEFUNC(getPlayerSpawnPosEventData_getTeam), 0);
	rb_define_method(c_get_player_spawn_pos_event_data, "pos", VALUEFUNC(getPlayerSpawnPosEventData_getPos), 0);
	rb_define_method(c_get_player_spawn_pos_event_data, "pos=", VALUEFUNC(getPlayerSpawnPosEventData_setPos), 1);
	rb_define_method(c_get_player_spawn_pos_event_data, "time", VALUEFUNC(getPlayerSpawnPosEventData_getTime), 0);
	rb_define_method(c_get_player_spawn_pos_event_data, "rot", VALUEFUNC(getPlayerSpawnPosEventData_getRot), 0);
	rb_define_method(c_get_player_spawn_pos_event_data, "rot=", VALUEFUNC(getPlayerSpawnPosEventData_setRot), 1);
	rb_define_method(c_get_player_spawn_pos_event_data, "handled?", VALUEFUNC(getPlayerSpawnPosEventData_isHandled), 0);
	rb_define_method(c_get_player_spawn_pos_event_data, "handled=", VALUEFUNC(getPlayerSpawnPosEventData_setHandled), 1);

	// bz_AllowPlayerEventData
	
	c_allow_player_event_data = rb_define_class_under(bzflag_module,"AllowPlayerEventData", c_event_data);
	rb_define_method(c_allow_player_event_data, "playerID", VALUEFUNC(allowPlayerEventData_getPlayerID), 0);
	rb_define_method(c_allow_player_event_data, "callsign", VALUEFUNC(allowPlayerEventData_getCallsign), 0);
	rb_define_method(c_allow_player_event_data, "ipAddress", VALUEFUNC(allowPlayerEventData_getIpAddress), 0);
	rb_define_method(c_allow_player_event_data, "reason", VALUEFUNC(allowPlayerEventData_getReason), 0);
	rb_define_method(c_allow_player_event_data, "allow?", VALUEFUNC(allowPlayerEventData_isAllow), 0);
	rb_define_method(c_allow_player_event_data, "allow=", VALUEFUNC(allowPlayerEventData_setAllow), 1);
	rb_define_method(c_allow_player_event_data, "time", VALUEFUNC(allowPlayerEventData_getTime), 0);

	// bz_TickEventData
	
	c_tick_event_data = rb_define_class_under(bzflag_module,"TickEventData", c_event_data);
	rb_define_method(c_tick_event_data, "time", VALUEFUNC(tickEventData_getTime), 0);

	// bz_GenerateWorldEventData

	c_generate_world_event_data = rb_define_class_under(bzflag_module,"GenerateWorldEventData", c_event_data);
	rb_define_method(c_generate_world_event_data, "generated?", VALUEFUNC(generateWorldEventData_isGenerated), 0);
	rb_define_method(c_generate_world_event_data, "generated=", VALUEFUNC(generateWorldEventData_setGenerated), 1);
	rb_define_method(c_generate_world_event_data, "ctf?", VALUEFUNC(generateWorldEventData_isCtf), 0);
	rb_define_method(c_generate_world_event_data, "rabbit?", VALUEFUNC(generateWorldEventData_isRabbit), 0);
	rb_define_method(c_generate_world_event_data, "open_ffa?", VALUEFUNC(generateWorldEventData_isOpenFFA), 0);
	rb_define_method(c_generate_world_event_data, "world_file", VALUEFUNC(generateWorldEventData_getWorldFile), 0);
	rb_define_method(c_generate_world_event_data, "world_file=", VALUEFUNC(generateWorldEventData_setWorldFile), 1);
	rb_define_method(c_generate_world_event_data, "time", VALUEFUNC(generateWorldEventData_getTime), 0);

	// bz_GetPlayerInfoEventData
	
	c_get_player_info_event_data = rb_define_class_under(bzflag_module,"GetPlayerInfoEventData", c_event_data);
	rb_define_method(c_get_player_info_event_data, "player_id", VALUEFUNC(getPlayerInfoEventData_getPlayerID), 0);
	rb_define_method(c_get_player_info_event_data, "callsign", VALUEFUNC(getPlayerInfoEventData_getCallsign), 0);
	rb_define_method(c_get_player_info_event_data, "ip_address", VALUEFUNC(getPlayerInfoEventData_getIpAddress), 0);
	rb_define_method(c_get_player_info_event_data, "team", VALUEFUNC(getPlayerInfoEventData_getTeam), 0);
	rb_define_method(c_get_player_info_event_data, "admin?", VALUEFUNC(getPlayerInfoEventData_isAdmin), 0);
	rb_define_method(c_get_player_info_event_data, "verified?", VALUEFUNC(getPlayerInfoEventData_isVerified), 0);
	rb_define_method(c_get_player_info_event_data, "registered?", VALUEFUNC(getPlayerInfoEventData_isRegistered), 0);
	rb_define_method(c_get_player_info_event_data, "time", VALUEFUNC(getPlayerInfoEventData_getTime), 0);

	// bz_GetAutoTeamEventData (this is not really working when i tested
	// it in a ruby plugin)

	c_get_auto_team_event_data = rb_define_class_under(bzflag_module,"GetAutoTeamEventData", c_event_data);
	rb_define_method(c_get_auto_team_event_data, "player_id", VALUEFUNC(getAutoTeamEventData_getPlayerID), 0);
	rb_define_method(c_get_auto_team_event_data, "callsign", VALUEFUNC(getAutoTeamEventData_getCallsign), 0);
	rb_define_method(c_get_auto_team_event_data, "team", VALUEFUNC(getAutoTeamEventData_getTeam), 0);
	rb_define_method(c_get_auto_team_event_data, "handled?", VALUEFUNC(getAutoTeamEventData_isHandled), 0);
	rb_define_method(c_get_auto_team_event_data, "handled=", VALUEFUNC(getAutoTeamEventData_setHandled), 1);

	// bz_AllowSpawnData

	c_allow_spawn_data = rb_define_class_under(bzflag_module,"AllowSpawnData", c_event_data);
	rb_define_method(c_allow_spawn_data, "player_id", VALUEFUNC(allowSpawnData_getPlayerID), 0);
	rb_define_method(c_allow_spawn_data, "team", VALUEFUNC(allowSpawnData_getTeam), 0);
	rb_define_method(c_allow_spawn_data, "handled?", VALUEFUNC(allowSpawnData_isHandled), 0);
	rb_define_method(c_allow_spawn_data, "handled=", VALUEFUNC(allowSpawnData_setHandled), 1);
	rb_define_method(c_allow_spawn_data, "allow?", VALUEFUNC(allowSpawnData_isAllow), 0);
	rb_define_method(c_allow_spawn_data, "allow=", VALUEFUNC(allowSpawnData_setAllow), 1);
	rb_define_method(c_allow_spawn_data, "time", VALUEFUNC(allowSpawnData_getTime), 0);

	// bz_ListServerUpdateEvent

	c_list_server_update_event = rb_define_class_under(bzflag_module,"ListServerUpdateEvent", c_event_data);
	rb_define_method(c_list_server_update_event, "address", VALUEFUNC(listServerUpdateEvent_getAddress), 0);
	rb_define_method(c_list_server_update_event, "address=", VALUEFUNC(listServerUpdateEvent_setAddress), 1);
	rb_define_method(c_list_server_update_event, "description", VALUEFUNC(listServerUpdateEvent_getDescription), 0);
	rb_define_method(c_list_server_update_event, "description=", VALUEFUNC(listServerUpdateEvent_setDescription), 1);
	rb_define_method(c_list_server_update_event, "groups", VALUEFUNC(listServerUpdateEvent_getGroups), 0);
	rb_define_method(c_list_server_update_event, "groups=", VALUEFUNC(listServerUpdateEvent_setGroups), 1);
	rb_define_method(c_list_server_update_event, "handled?", VALUEFUNC(listServerUpdateEvent_isHandled), 0);
	rb_define_method(c_list_server_update_event, "handled=", VALUEFUNC(listServerUpdateEvent_setHandled), 1);
	rb_define_method(c_list_server_update_event, "time", VALUEFUNC(listServerUpdateEvent_getTime), 0);

	// bz_BanEventData

	c_ban_event_data = rb_define_class_under(bzflag_module,"BanEventData", c_event_data);
	rb_define_method(c_ban_event_data, "banner_id", VALUEFUNC(banEventData_getBannerID), 0);
	rb_define_method(c_ban_event_data, "bannee_id", VALUEFUNC(banEventData_getBanneeID), 0);
	rb_define_method(c_ban_event_data, "duration", VALUEFUNC(banEventData_getDuration), 0);
	rb_define_method(c_ban_event_data, "ip_address", VALUEFUNC(banEventData_getIpAddress), 0);
	rb_define_method(c_ban_event_data, "reason", VALUEFUNC(banEventData_getReason), 0);

	// bz_HostBanEventData

	c_host_ban_event_data = rb_define_class_under(bzflag_module,"HostBanEventData", c_event_data);
	rb_define_method(c_host_ban_event_data, "banner_id", VALUEFUNC(hostBanEventData_getBannerID), 0);
	rb_define_method(c_host_ban_event_data, "duration", VALUEFUNC(hostBanEventData_getDuration), 0);
	rb_define_method(c_host_ban_event_data, "host_pattern", VALUEFUNC(hostBanEventData_getHostPattern), 0);
	rb_define_method(c_host_ban_event_data, "reason", VALUEFUNC(hostBanEventData_getReason), 0);

	// bz_KickEventData

	c_kick_event_data = rb_define_class_under(bzflag_module,"KickEventData", c_event_data);
	rb_define_method(c_kick_event_data, "kicker_id", VALUEFUNC(kickEventData_getKickerID), 0);
	rb_define_method(c_kick_event_data, "kicked_id", VALUEFUNC(kickEventData_getKickedID), 0);
	rb_define_method(c_kick_event_data, "reason", VALUEFUNC(kickEventData_getReason), 0);

	// bz_KillEventData
	
	c_kill_event_data = rb_define_class_under(bzflag_module,"KillEventData", c_event_data);
	rb_define_method(c_kill_event_data, "killer_id", VALUEFUNC(killEventData_getKillerID), 0);
	rb_define_method(c_kill_event_data, "killed_id", VALUEFUNC(killEventData_getKilledID), 0);
	rb_define_method(c_kill_event_data, "reason", VALUEFUNC(killEventData_getReason), 0);

	// bz_PlayerPausedEventData

	c_player_paused_event_data = rb_define_class_under(bzflag_module,"PlayerPausedEventData", c_event_data);
	rb_define_method(c_player_paused_event_data, "player_id", VALUEFUNC(playerPausedEventData_getPlayerID), 0);
	rb_define_method(c_player_paused_event_data, "time", VALUEFUNC(playerPausedEventData_getTime), 0);
	rb_define_method(c_player_paused_event_data, "paused?", VALUEFUNC(playerPausedEventData_isPaused), 0);

	// bz_MessageFilteredEventData

	// bz_GameStartEndEventData
	c_game_start_end_event_data = rb_define_class_under(bzflag_module,"GameStartEndEventData", c_event_data);
	rb_define_method(c_game_start_end_event_data, "time", VALUEFUNC(gameStartEndEventData_getTime), 0);
	rb_define_method(c_game_start_end_event_data, "duration", VALUEFUNC(gameStartEndEventData_getDuration), 0);

	// bz_SlashCommandEventData
	c_slash_command_event_data = rb_define_class_under(bzflag_module,"SlashCommandEventData", c_event_data);
	rb_define_method(c_slash_command_event_data, "from", VALUEFUNC(slashCommandEventData_getFrom), 0);
	rb_define_method(c_slash_command_event_data, "time", VALUEFUNC(slashCommandEventData_getTime), 0);

	// bz_PlayerAuthEventData


	// bz_ServerMsgEventData

	c_server_msg_event_data = rb_define_class_under(bzflag_module,"ServerMsgEventData", c_event_data);
	rb_define_method(c_server_msg_event_data, "to", VALUEFUNC(serverMsgEventData_getTo), 0);
	rb_define_method(c_server_msg_event_data, "team", VALUEFUNC(serverMsgEventData_getTeam), 0);
	rb_define_method(c_server_msg_event_data, "message", VALUEFUNC(serverMsgEventData_getMessage), 0);
	rb_define_method(c_server_msg_event_data, "time", VALUEFUNC(serverMsgEventData_getTime), 0);

	// bz_ShotFiredEventData

	c_shot_fired_event_data = rb_define_class_under(bzflag_module,"ShotFiredEventData", c_event_data);
	rb_define_method(c_shot_fired_event_data, "player_id", VALUEFUNC(shotFiredEventData_getPlayerID), 0);
	rb_define_method(c_shot_fired_event_data, "pos", VALUEFUNC(shotFiredEventData_getPos), 0);
	rb_define_method(c_shot_fired_event_data, "type", VALUEFUNC(shotFiredEventData_getType), 0);
	rb_define_method(c_shot_fired_event_data, "type=", VALUEFUNC(shotFiredEventData_setType), 1);
	rb_define_method(c_shot_fired_event_data, "changed?", VALUEFUNC(shotFiredEventData_isChanged), 0);
	rb_define_method(c_shot_fired_event_data, "changed=", VALUEFUNC(shotFiredEventData_setChanged), 1);


	// bz_PlayerUpdateEventData

	// bz_NetTransferEventData

	// bz_LogingEventData

	// bz_ShotEndedEventData

	c_shot_ended_event_data = rb_define_class_under(bzflag_module,"ShotEndedEventData", c_event_data);
	rb_define_method(c_shot_ended_event_data, "player_id", VALUEFUNC(shotEndedEventData_getPlayerID), 0);
	rb_define_method(c_shot_ended_event_data, "shot_id", VALUEFUNC(shotEndedEventData_getShotID), 0);
	rb_define_method(c_shot_ended_event_data, "explode?", VALUEFUNC(shotEndedEventData_isExplode), 0);
	
	
	// bz_FlagTransferredEventData

	// bz_FlagGrabbedEventData (still bug here, but probably in bzflag
	// it selfs. A bzmessage in this event crashes the client).

	c_flag_grabbed_event_data = rb_define_class_under(bzflag_module,"FlagGrabbedEventData", c_event_data);
	rb_define_method(c_flag_grabbed_event_data, "player_id", VALUEFUNC(flagGrabbedEventData_getPlayerID), 0);
	rb_define_method(c_flag_grabbed_event_data, "flag_id", VALUEFUNC(flagGrabbedEventData_getFlagID), 0);
	rb_define_method(c_flag_grabbed_event_data, "flag_type", VALUEFUNC(flagGrabbedEventData_getFlagType), 0);
	rb_define_method(c_flag_grabbed_event_data, "pos", VALUEFUNC(flagGrabbedEventData_getPos), 0);

	// bz_FlagDroppedEventData

	c_flag_dropped_event_data = rb_define_class_under(bzflag_module,"FlagDroppedEvenData", c_event_data);
	rb_define_method(c_flag_dropped_event_data, "player_id", VALUEFUNC(flagDroppedEventData_getPlayerID), 0);
	rb_define_method(c_flag_dropped_event_data, "flag_id", VALUEFUNC(flagDroppedEventData_getFlagID), 0);
	rb_define_method(c_flag_dropped_event_data, "flag_type", VALUEFUNC(flagDroppedEventData_getFlagType), 0);
	rb_define_method(c_flag_dropped_event_data, "pos", VALUEFUNC(flagDroppedEventData_getPos), 0);


}

